package com.zmj.sy.mom.srv.aps.service;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DatePattern;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.conditions.query.LambdaQueryChainWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.google.common.collect.Lists;
import com.zmj.sy.mom.srv.aps.bean.dto.apsmes.DoWorksDto;
import com.zmj.sy.mom.srv.aps.bean.dto.wms.PartsReportingAddDto;
import com.zmj.sy.mom.srv.aps.bean.entity.base.BaseEntity;
import com.zmj.sy.mom.srv.aps.bean.entity.base.PoolItem;
import com.zmj.sy.mom.srv.aps.bean.entity.base.PoolLog;
import com.zmj.sy.mom.srv.aps.bean.entity.base.PoolPart;
import com.zmj.sy.mom.srv.aps.bean.entity.mes.*;
import com.zmj.sy.mom.srv.aps.bean.entity.order.*;
import com.zmj.sy.mom.srv.aps.bean.entity.resource.*;
import com.zmj.sy.mom.srv.aps.bean.entity.third.SinoCamReceiveNestCheck;
import com.zmj.sy.mom.srv.aps.bean.entity.third.SinoCamReceiveNestNest;
import com.zmj.sy.mom.srv.aps.bean.entity.third.SinoCamReceiveNestPart;
import com.zmj.sy.mom.srv.aps.bean.entity.third.SinoCamReceiveNestPlate;
import com.zmj.sy.mom.srv.aps.bean.entity.workshop.WorkshopPlateToPartRes;
import com.zmj.sy.mom.srv.aps.bean.vo.base.BaseIdReqVo;
import com.zmj.sy.mom.srv.aps.bean.vo.base.BaseListResVo;
import com.zmj.sy.mom.srv.aps.bean.vo.base.BasePageResVo;
import com.zmj.sy.mom.srv.aps.bean.vo.base.Result;
import com.zmj.sy.mom.srv.aps.bean.vo.plate.PlateDelPartReqVo;
import com.zmj.sy.mom.srv.aps.bean.vo.plate.PlatePartListResVo;
import com.zmj.sy.mom.srv.aps.bean.vo.work.PoolItemVo;
import com.zmj.sy.mom.srv.aps.bean.vo.workshop.*;
import com.zmj.sy.mom.srv.aps.config.ProjectConfig;
import com.zmj.sy.mom.srv.aps.feign.*;
import com.zmj.sy.mom.srv.aps.lock.RedissonLockClient;
import com.zmj.sy.mom.srv.aps.mapper.*;
import com.zmj.sy.mom.srv.aps.utils.*;
import com.zmj.sy.mom.srv.mbd.api.api.MomSrvMbdApiClient;
import com.zmj.sy.mom.srv.mbd.api.bean.dto.match.MatchFindPalletReqDto;
import com.zmj.sy.mom.srv.mbd.api.bean.dto.match.MatchFindPalletResDto;
import com.zmj.sy.mom.srv.mbd.api.bean.dto.match.MatchFindPartReqDto;
import com.zmj.sy.mom.srv.mbd.api.bean.dto.match.MatchFindPartResDto;
import com.zmj.sy.mom.srv.mbd.api.bean.entity.AssemblyInfo;
import com.zmj.sy.mom.srv.mbd.api.utils.MkBeanUtils;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;
import org.springframework.util.CollectionUtils;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.concurrent.CompletableFuture;
import java.util.function.BinaryOperator;
import java.util.function.Function;
import java.util.stream.Collectors;

import static com.baomidou.mybatisplus.core.toolkit.Wrappers.lambdaQuery;


@Slf4j
@RequiredArgsConstructor
@Service
public class WorkshopService {

    private final char[] UNIQUE_CODE_ALPHABET = {'1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'J', 'K', 'L', 'M', 'N', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z'};

    private final WorkshopMapper workshopMapper;

    private final StationMapper stationMapper;

    private final PartUtilService partUtilService;

    private final GroupMapper groupMapper;

    private final SinoCamReceiveNestPlateMapper sinoCamReceiveNestPlateMapper;

    private final SinoCamReceiveNestPartMapper sinoCamReceiveNestPartMapper;

    private final ApsWorkDetailMapper apsWorkDetailMapper;

    private final ApsWorkOrderMapper apsWorkOrderMapper;

    private final PositionMapper positionMapper;

    private final PartPalletMapper partPalletMapper;

    private final WorkRecordMapper workRecordMapper;

    private final PartService partService;
    private final PartMapper partMapper;

    private final MatchPalletMapper matchPalletMapper;

    private final PartExceptService partExceptService;
    private final StationService stationService;
    private final PhaseGroupMapper phaseGroupMapper;

    private final RedissonLockClient redissonLockClient;

    private final PlateMapper plateMapper;

    private final WmsPlatePickMapper wmsPlatePickMapper;

    private final ApsOrderMapper apsOrderMapper;

    private final OrderMapper orderMapper;

    private final WorkDetailTaskMapper workDetailTaskMapper;

    private final MatchTaskMapper matchTaskMapper;

    private final MomSrvMbdApiClient momSrvMbdApiClient;
    private final PartLogMapper partLogMapper;

    private final OrderBomMapper orderBomMapper;

    private final PhaseMapper phaseMapper;
    private final ApsMesFeign apsMesFeign;
//    private final QmsOldApiClient qmsOldApiClient;

    private final MatchTaskDetailMapper matchDetailTaskMapper;

    private final PlateUtils plateUtils;

    private final WmsApiClient wmsApiClient;

    private final MatchTaskDetailMapper matchTaskDetailMapper;

    private final MatchDetailTaskLogMapper matchDetailTaskLogMapper;

    private final PudaApiClient pudaApiClient;

    private final SinoCamReceiveNestNestMapper sinoCamReceiveNestNestMapper;

    private final PlatePhaseMapper platePhaseMapper;

    private final ProjectConfig projectConfig;

    private final StaffApiClient staffApiClient;
    private final MbdFeign mbdFeign;

    private final PickMapper pickMapper;
    private final MkPartUtils mkPartUtils;
    private final WorkRecordReplyMapper workRecordReplyMapper;
    private final ApsInformQmsService apsInformQmsService;
    private final PoolItemMapper poolItemMapper;
    private final PoolPartMapper poolPartMapper;
    private final PoolLogMapper poolLogMapper;
    private final SinoCamReceiveNestCheckMapper sinoCamReceiveNestCheckMapper;
    private final SinoCamService sinoCamService;


    public List<WorkshopDashboardResVo> dashboard(List<WorkshopDashboardResVo> list) {
        LambdaQueryWrapper<Group> wrapper = lambdaQuery();
        wrapper.isNotNull(Group::getWorkshopTaskTitleVal);
        List<Group> groupList = groupMapper.selectList(wrapper);

        Map<String, List<Group>> collect1 = groupList.stream().collect(Collectors.groupingBy(Group::getWorkshopTaskTitleVal));
        for (WorkshopDashboardResVo resVo : list) {
            List<Group> groups = collect1.get(resVo.getCode());
            if (groups == null) {
                continue;
            }

            List<WorkshopDashboardDataResVo> collect2 = groups.stream()
                    .sorted(Comparator.comparing(Group::getSeq))
                    .map(e -> {
                        WorkshopDashboardDataResVo rr = new WorkshopDashboardDataResVo();
                        rr.setId(e.getId());
                        rr.setName(e.getName());
                        rr.setMyCode(e.getMyCode());
                        rr.setWorkshopTaskTitleVal(e.getWorkshopTaskTitleVal());
                        rr.setStartReportWorkVal(e.getStartReportWorkVal());
                        return rr;
                    })
                    .collect(Collectors.toList());
            resVo.getData().addAll(collect2);

        }

        return list;
    }

    public BasePageResVo<WorkshopPlateToPartResVo> plateToPart(WorkshopPlateToPartReqVo reqVo) {
        List<Integer> status = reqVo.getStatus();
        if (CollectionUtils.isEmpty(status)) {
            status = Arrays.asList(1, 2);
        }
        LocalDateTime startTime = reqVo.getStartTime();
        if (startTime == null) {
            startTime = LocalDateTime.now().minusDays(15);
        }
        LocalDateTime endTime = reqVo.getEndTime();
        if (endTime == null) {
            endTime = LocalDateTime.now().plusDays(15);
        }

        Group group = groupMapper.selectById(reqVo.getId());
        Page<WorkDetailTask> plateTasks = workDetailTaskMapper.lambdaQuery()
                .eq(WorkDetailTask::getGroupCode, group.getMyCode())
                .eq(WorkDetailTask::getType, 1)
                .in(WorkDetailTask::getStatus, status)
                .ge(WorkDetailTask::getCreateDateTime, startTime.format(DatePattern.NORM_DATETIME_FORMATTER))
                .le(WorkDetailTask::getCreateDateTime, endTime.format(DatePattern.NORM_DATETIME_FORMATTER))
                .like(org.springframework.util.StringUtils.hasText(reqVo.getGroupCode()), WorkDetailTask::getGroupCode, reqVo.getGroupCode())
                .like(org.springframework.util.StringUtils.hasText(reqVo.getMaterCode()), WorkDetailTask::getMaterCode, reqVo.getMaterCode())
                .page(reqVo.toPage());

        if (CollUtil.isEmpty(plateTasks.getRecords())) {
            return BasePageResVo.empty();
        }

        List<Plate> list = plateMapper.lambdaQuery().in(Plate::getMaterCode, plateTasks.getRecords().stream().map(WorkDetailTask::getMaterCode).collect(Collectors.toList())).list();
        Map<String, Plate> map = list.stream().collect(Collectors.toMap(e -> e.getMaterCode(), Function.identity()));

        Map<String, Phase> phaseMap = phaseMapper.lambdaQuery().isNotNull(Phase::getMyCode).list().stream().collect(Collectors.toMap(Phase::getMyCode, Function.identity()));


        List<WorkshopPlateToPartResVo> plateList = plateTasks.getRecords().stream()
                .map(task -> {

                    WorkshopPlateToPartResVo plateToPartResVo = new WorkshopPlateToPartResVo();
                    plateToPartResVo.setId(task.getId());
                    plateToPartResVo.setOrderCode(task.getOrderCode());
                    plateToPartResVo.setMaterCode(task.getMaterCode());
                    plateToPartResVo.setMaterName("钢板");
                    plateToPartResVo.setPhaseCode(task.getPhaseCode());
                    plateToPartResVo.setPhaseName(phaseMap.get(task.getPhaseCode()).getName());
                    plateToPartResVo.setSpec(task.getNorm());
                    plateToPartResVo.setMaterial(task.getTexture());
                    plateToPartResVo.setWeight(task.getWeight() != null ? task.getWeight().toString() : "10000");
                    plateToPartResVo.setStatus(task.getStatus());
                    plateToPartResVo.setPlanStartDateTime(task.getPlanStartDateTime());
                    plateToPartResVo.setPlanEndDateTime(task.getPlanEndDateTime());
                    plateToPartResVo.setActualStartDateTime(task.getActualStartDateTime());
                    plateToPartResVo.setActualEndDateTime(task.getActualEndDateTime());
                    plateToPartResVo.setGroupCode(task.getGroupCode());
                    plateToPartResVo.setNestPlateId(task.getNestPlateId());
                    String mapUrl = sinoCamReceiveNestPlateMapper.selectMapUrl(task.getMaterCode());
                    plateToPartResVo.setNestingDrawing(mapUrl);

                    WmsPlatePick one = wmsPlatePickMapper.lambdaQuery().eq(WmsPlatePick::getMaterialId, task.getMaterCode()).orderByDesc(WmsPlatePick::getId).last(" limit 1 ").one();
                    if (one != null) {
                        plateToPartResVo.setNestId(one.getNestId());
                        plateToPartResVo.setPickingListNo(one.getPickingListNo());
                    }


                    Plate plate = map.get(task.getMaterCode());
                    plateToPartResVo.setWorkChain(plate.getWorkChain());

                    List<PlatePhase> phaseList = platePhaseMapper.lambdaQuery()
                            .eq(PlatePhase::getPlateCode, plate.getMaterCode())
                            .orderByAsc(PlatePhase::getPhaseSeq)
                            .list();

                    PlatePhase platePhase = phaseList.stream().filter(e -> e.getPhaseCode().equals(plate.getPhaseCode())).findFirst().get();
                    Optional<PlatePhase> min = phaseList.stream().filter(e -> e.getPhaseSeq() > platePhase.getPhaseSeq()).min(Comparator.comparing(PlatePhase::getPhaseSeq));
                    if (min.isPresent()) {
                        PlatePhase ph = min.get();
                        plateToPartResVo.setNextPhaseCode(ph.getPhaseCode());
                        plateToPartResVo.setNextGroupCode(ph.getGroupCode());
                    }

                    /*
                    List<String> workChainList = Arrays.asList(plate.getWorkChain().split("-"));
                    int i = workChainList.indexOf(plateToPartResVo.getPhaseCode());
                    if (i < workChainList.size() - 1) {
                        i++;
                        plateToPartResVo.setNextPhaseCode(workChainList.get(i));
                        String s = Arrays.asList(plate.getChainGroupCode().split(",")).get(i);
                        plateToPartResVo.setNextGroupCode(s);
                    }

                     */


                    return plateToPartResVo;
                })
                .collect(Collectors.toList());

        return new BasePageResVo<>(plateTasks.getTotal(), plateList);
    }

    /**
     * @Description: 通过一个sql获取待加工任务列表
     * @author: hejiahui
     * @since: 2024/11/4 14:16
     */
    public BasePageResVo<WorkshopPlateToPartResVo> plateToPartBySql(WorkshopPlateToPartReqVo reqVo) {
        List<Integer> status = reqVo.getStatus();
        if (CollectionUtils.isEmpty(status)) {
            status = Arrays.asList(1, 2);
        }
        QueryWrapper<?> plateToPartQuery = new QueryWrapper<>();
        plateToPartQuery.eq("gro.id", reqVo.getId());
        plateToPartQuery.eq("task.type", 1);
        plateToPartQuery.in("task.status", status);
        LocalDateTime startTime = reqVo.getStartTime();
        LocalDateTime endTime = reqVo.getEndTime();
    /* if(status.contains(1)||status.contains(2)){
            if (startTime == null) {
                startTime = LocalDateTime.now().minusDays(15);
            }
            if (endTime == null) {
                endTime = LocalDateTime.now().plusDays(15);
            }
        }*/
        if(startTime != null){
            plateToPartQuery.ge("task.create_date_time", startTime.format(DatePattern.NORM_DATETIME_FORMATTER));
        }
        if(endTime != null){
            plateToPartQuery.le("task.create_date_time", endTime.format(DatePattern.NORM_DATETIME_FORMATTER));
        }

        plateToPartQuery.like(org.springframework.util.StringUtils.hasText(reqVo.getGroupCode()), "task.group_code", reqVo.getGroupCode());
        plateToPartQuery.like(org.springframework.util.StringUtils.hasText(reqVo.getMaterCode()), "task.mater_code", reqVo.getMaterCode());
        plateToPartQuery.like(org.springframework.util.StringUtils.hasText(reqVo.getNestId()), "mesPla.nest_id", reqVo.getNestId());
        plateToPartQuery.like(org.springframework.util.StringUtils.hasText(reqVo.getNestId()), "mesPla.nest_id", reqVo.getNestId());
        plateToPartQuery.like(org.springframework.util.StringUtils.hasText(reqVo.getPickingListNo()), "pick.picking_list_no ", reqVo.getPickingListNo());
        plateToPartQuery.eq(org.springframework.util.StringUtils.hasText(reqVo.getSpec()), "mesPla.norm ", reqVo.getSpec());
        if (status.contains(3)) {
            plateToPartQuery.orderByDesc("task.actual_end_date_time");
        }
        Page<WorkshopPlateToPartRes> plateList = workshopMapper.plateToPartList(reqVo.toPage(), plateToPartQuery);

        //获取钢板开报工人员
        Map<String, Map<String, Object>> startPhaseMap = new HashMap<>();
        Map<String, Map<String, Object>> endPhaseMap = new HashMap<>();
        List<WorkshopPlateToPartRes> records = plateList.getRecords();
        if (!CollectionUtils.isEmpty(records)) {
            final Set<String> materSet = records.stream().map(WorkshopPlateToPartRes::getMaterCode).collect(Collectors.toSet());
            final Set<String> phaseSet = records.stream().map(WorkshopPlateToPartRes::getPhaseCode).collect(Collectors.toSet());
            //开工
            QueryWrapper<?> reportQuery = new QueryWrapper<>();
            reportQuery.in("stRe.pallet_number", materSet);
            reportQuery.in("stRe.phase_code", phaseSet);
            List<Map<String, Object>> startReportList = workshopMapper.getStartReportList(reportQuery);
            if (!CollectionUtils.isEmpty(startReportList)) {
                startPhaseMap = startReportList.stream().collect(Collectors.toMap(e -> e.get("pallet_number").toString() + e.get("phase_code"), e -> e, BinaryOperator.maxBy(Comparator.comparing(e -> e.get("id").toString()))));
            }
            //报工
            List<Map<String, Object>> endReportList = workshopMapper.getEndReportList(reportQuery);
            if (!CollectionUtils.isEmpty(endReportList)) {
                endPhaseMap = endReportList.stream().collect(Collectors.toMap(e -> e.get("pallet_number").toString() + e.get("phase_code"), e -> e, BinaryOperator.maxBy(Comparator.comparing(e -> e.get("id").toString()))));
            }
        }


        for (WorkshopPlateToPartRes record : plateList.getRecords()) {
            List<PlatePhase> phaseList = platePhaseMapper.lambdaQuery()
                    .eq(PlatePhase::getPlateCode, record.getMaterCode())
                    .orderByAsc(PlatePhase::getPhaseSeq)
                    .list();
            String pngName = record.getNestId().contains(".") ? record.getNestId().substring(0, record.getNestId().indexOf(".")) + ".png" : record.getNestId() + ".png";
            record.setNestingDrawing(String.format(projectConfig.getUrlPre(), pngName, record.getNestingDrawing()));

            //PlatePhase platePhase = phaseList.stream().filter(e -> e.getPhaseCode().equals(record.getPlaPhaseCode())).findFirst().get();
            PlatePhase platePhase = phaseList.stream().filter(e -> e.getPhaseCode().equals(record.getPlaPhaseCode())).findFirst().orElse(null);
            if (platePhase == null) {
                continue;
            }
            Optional<PlatePhase> min = phaseList.stream().filter(e -> e.getPhaseSeq() > platePhase.getPhaseSeq()).min(Comparator.comparing(PlatePhase::getPhaseSeq));
            if (min.isPresent()) {
                PlatePhase ph = min.get();
                record.setNextPhaseCode(ph.getPhaseCode());
                record.setNextGroupCode(ph.getGroupCode());
            }
            //获取钢板开报工人员
            Map<String, Object> startPerson = startPhaseMap.get(record.getMaterCode() + record.getPhaseCode());
            if (!ObjectUtils.isEmpty(startPerson)) {
                record.setStartStaff((String) startPerson.get("staff"));
            }
            final Map<String, Object> stringObjectMap = endPhaseMap.get(record.getMaterCode() + record.getPhaseCode());
            if (!ObjectUtils.isEmpty(stringObjectMap)) {
                record.setEndStaff((String) stringObjectMap.get("staff"));
            }
        }
        List<WorkshopPlateToPartResVo> voRecords = plateList.getRecords().stream().map(e -> {
            WorkshopPlateToPartResVo vo = new WorkshopPlateToPartResVo();
            BeanUtils.copyProperties(e, vo);
            return vo;
        }).collect(Collectors.toList());
        Page<WorkshopPlateToPartResVo> resVoPage = new Page<>();
        BeanUtils.copyProperties(plateList, resVoPage);
        resVoPage.setRecords(voRecords);
        return BasePageResVo.of(resVoPage, WorkshopPlateToPartResVo.class);
    }

    public BasePageResVo<WorkshopComponentToComponentResVo> componentToComponent(WorkshopComponentToComponentReqVo reqVo) {
        QueryWrapper<ApsWorkDetail> query = Wrappers.query();
//        LocalDate now = LocalDate.now();plateToPart
//        query.between("t3.plan_start_date_time", now.atStartOfDay(), now.plusDays(8).atStartOfDay().minusSeconds(1));
//        query.eq("task.group_code", reqVo.getGroupCode());
        query.eq("wd.group_id", reqVo.getId());
        if (reqVo.getStatus() == null) {
            query.in("task.status", 1, 2);
        } else {
            query.eq("task.status", reqVo.getStatus());
        }
//        query.eq("task.status", reqVo.getStatus());

        query.like(StringUtils.hasText(reqVo.getConstructNo()), "o.construct_no", reqVo.getConstructNo());
        query.like(StringUtils.hasText(reqVo.getWorkOrderCode()), "wo.work_order_code", reqVo.getWorkOrderCode());
        query.like(StringUtils.hasText(reqVo.getUniqueCode()), "wd.unique_code", reqVo.getUniqueCode());
        query.like(StringUtils.hasText(reqVo.getMaterCode()), "wd.mater_no", reqVo.getMaterCode());

        query.orderByAsc("wd.aps_order_id");
        query.orderByAsc("wd.plan_start_date_time");

        Page<WorkshopComponentToComponentResVo> partList = apsWorkDetailMapper.listComponentToComponent(reqVo.toPage(), query);
        BasePageResVo<WorkshopComponentToComponentResVo> resVo = BasePageResVo.of(partList, WorkshopComponentToComponentResVo.class);

        for (WorkshopComponentToComponentResVo datum : resVo.getData()) {
            // 开始分捡后的下一道工序
            QueryWrapper<ApsWorkDetail> query1 = Wrappers.query();
            query1.eq("aps_work_order_id", datum.getApsWorkOrderId());
            query1.gt("phase_seq", datum.getPhaseSeq());
            Integer minPhaseSeq = apsWorkDetailMapper.minPhaseSeq(query1);
            if (minPhaseSeq != null) {
                ApsWorkDetail nextList = apsWorkDetailMapper.lambdaQuery()
                        .eq(ApsWorkDetail::getApsWorkOrderId, datum.getApsWorkOrderId())
                        .eq(ApsWorkDetail::getPhaseSeq, minPhaseSeq)
                        .orderByAsc(ApsWorkDetail::getPhaseSeq)
                        .last(" limit 1")
                        .one();

                if (nextList != null) {
                    datum.setNextGroupCode(nextList.getGroupCode());
                    datum.setNextPhaseCode(nextList.getPhaseCode());
                }
            }
        }
        return resVo;
    }

    public BasePageResVo<WorkshopPartToPartResVo> partToPart(WorkshopPartToPartReqVo reqVo) {

        if (CollUtil.isEmpty(reqVo.getStatus())) {
            reqVo.setStatus(Arrays.asList(1, 2));
        }

        Group group = groupMapper.selectById(reqVo.getId());

        QueryWrapper<ApsWorkDetail> query = Wrappers.query();
        query.eq("task.group_code", group.getMyCode());
        query.in("task.status", reqVo.getStatus());
        query.like(org.springframework.util.StringUtils.hasText(reqVo.getMaterCode()), "wd.mater_no", reqVo.getMaterCode());
        query.like(org.springframework.util.StringUtils.hasText(reqVo.getWorkOrderCode()), "wo.work_order_code", reqVo.getWorkOrderCode());
        query.like(org.springframework.util.StringUtils.hasText(reqVo.getMaterName()), "wd.mater_name", reqVo.getMaterName());
        query.like(org.springframework.util.StringUtils.hasText(reqVo.getConstructNo()), "o.construct_no", reqVo.getConstructNo());
        query.orderByAsc("wd.aps_order_id", "wd.plan_start_date_time");
        Page<WorkshopPartToPartResVo> partList = apsWorkDetailMapper.listPartToPart(query, reqVo.toPage());
        for (WorkshopPartToPartResVo workshopPartToPartResVo : partList.getRecords()) {
            if (org.springframework.util.StringUtils.hasText(workshopPartToPartResVo.getPartPath())) {
                workshopPartToPartResVo.setPartPath(workshopPartToPartResVo.getPartPath());
            }
        }

        BasePageResVo<WorkshopPartToPartResVo> resVo = new BasePageResVo<>(partList.getTotal(), partList.getRecords());
        for (WorkshopPartToPartResVo datum : resVo.getData()) {
            // 开始分捡后的下一道工序
            QueryWrapper<ApsWorkDetail> query1 = Wrappers.query();
            query1.eq("aps_work_order_id", datum.getApsWorkOrderId());
            query1.gt("phase_seq", datum.getPhaseSeq());
            Integer minPhaseSeq = apsWorkDetailMapper.minPhaseSeq(query1);
            if (minPhaseSeq != null) {
                ApsWorkDetail nextList = apsWorkDetailMapper.lambdaQuery()
                        .eq(ApsWorkDetail::getApsWorkOrderId, datum.getApsWorkOrderId())
                        .ge(ApsWorkDetail::getPhaseSeq, minPhaseSeq)
                        .orderByAsc(ApsWorkDetail::getPhaseSeq)
                        .last(" limit 1")
                        .one();

                if (nextList != null) {
                    datum.setNextGroupCode(nextList.getGroupCode());
                    datum.setNextPhaseCode(nextList.getPhaseCode());
                }
            }
        }
        return resVo;
    }

    public BasePageResVo<WorkshopPartToComponentResVo> partToComponent(WorkshopPartToComponentReqVo reqVo) {
        QueryWrapper<ApsWorkDetail> query = Wrappers.query();
        query.in("wd.phase_code", WorkshopProp.PZ_PHASE_CODE, WorkshopProp.PD_PHASE_CODE, WorkshopProp.XH_PHASE_CODE);
        if (reqVo.getStatus() != null) {
            query.eq("wd.`status`", reqVo.getStatus());
        } else {
            query.in("wd.`status`", 2, 3);
        }
        query.eq("wd.group_id", reqVo.getId());
        query.ne("wd.order_type", 2);
//        query.ge("o.order_status", 7);
        if (org.springframework.util.StringUtils.hasText(reqVo.getPackageCode())) {
            query.eq(reqVo.getPackageCode() != null, "ao.seq", Integer.valueOf(reqVo.getPackageCode().split("-")[1]));
        }

        query.like(org.springframework.util.StringUtils.hasText(reqVo.getMaterName()), "wd.mater_name", reqVo.getMaterName());
        query.like(org.springframework.util.StringUtils.hasText(reqVo.getMaterCode()), "wd.mater_no", reqVo.getMaterCode());
        query.like(org.springframework.util.StringUtils.hasText(reqVo.getWorkOrderCode()), "wo.work_order_code", reqVo.getWorkOrderCode());
        query.like(org.springframework.util.StringUtils.hasText(reqVo.getUniqueCode()), "wd.unique_code", reqVo.getUniqueCode());

        if (reqVo.getStatus() != null && reqVo.getStatus() == 4) {
            query.orderByDesc("wd.modify_date_time");
        } else {
            query.orderByAsc("ao.seq", "wd.plan_start_date_time");
        }
        int size = reqVo.getSize();
        int page = reqVo.getPage();
        if (reqVo.getStatus() != null && reqVo.getStatus() == 4) {
        } else {
            reqVo.setPage(1);
            reqVo.setSize(1000);
        }
        query.like(StringUtils.hasText(reqVo.getConstructNo()), "o.construct_no", reqVo.getConstructNo());

        Page<WorkshopPartToComponentResVo> componentList = apsWorkDetailMapper.listPartToComponent(reqVo.toPage(), query);
        reqVo.setSize(size);
        reqVo.setPage(page);
        for (WorkshopPartToComponentResVo record : componentList.getRecords()) {
            record.setPackageCode(PkgUtils.gen(record.getPackageSeq()));
        }
        List<WorkshopPartToComponentResVo> assemblList = new LinkedList<>();
        BasePageResVo<WorkshopPartToComponentResVo> resVo = null;
        if (reqVo.getStatus() != null && reqVo.getStatus() == 4) {
            assemblList = componentList.getRecords();
            resVo = new BasePageResVo<>(componentList.getTotal(), assemblList);
        } else {
            List<WaitWorkAsseVo> waitAsseWorks1 = findAsseWorks(reqVo.getId(), componentList.getRecords().stream().map(WorkshopPartToComponentResVo::getMaterCode).distinct().collect(Collectors.toList()));
//            Map<String, BigDecimal> waitAsseWorks = waitAsseWorks1.stream().collect(Collectors.toMap(WaitWorkAsseVo::getAssemblyNumber, WaitWorkAsseVo::getTotalCount, (e1, e2) -> e1));
            Map<String, Map<String, BigDecimal>> waitAsseWorks = waitAsseWorks1.stream().collect(Collectors.groupingBy(WaitWorkAsseVo::getConstructNo, Collectors.toMap(WaitWorkAsseVo::getAssemblyNumber, WaitWorkAsseVo::getTotalCount, (e1, e2) -> {
                e1 = e1.add(e2);
                return e1;
            })));

            for (WorkshopPartToComponentResVo e : componentList.getRecords()) {
                BigDecimal count = waitAsseWorks.getOrDefault(e.getConstructNo(), new HashMap<>()).get(e.getMaterCode());
                if (org.apache.commons.lang3.ObjectUtils.isEmpty(count)) {
                    waitAsseWorks.remove(e.getMaterCode());
                } else {
                    if (count.intValue() >= 1) {
                        if (count.intValue() >= e.getTotalCount().subtract(e.getFinishCount()).intValue()) {
                            assemblList.add(e);
                            count = count.subtract(e.getTotalCount()).add(e.getFinishCount());
                            //更新剩余数量
                            waitAsseWorks.computeIfAbsent(e.getConstructNo(), k -> new HashMap<>()).put(e.getMaterCode(), count);
                        } else {
                            e.setTotalCount(count.add(e.getFinishCount()));
                            assemblList.add(e);
                            count = new BigDecimal(0);
                            waitAsseWorks.computeIfAbsent(e.getConstructNo(), k -> new HashMap<>()).put(e.getMaterCode(), count);
                        }
                    } else {
                        waitAsseWorks.remove(e.getMaterCode());
                    }
                }
            }
            PageUtils pageUtils = new PageUtils(reqVo.getPage(), reqVo.getSize(), assemblList);
            List<WorkshopPartToComponentResVo> list = pageUtils.getData();
            for (WorkshopPartToComponentResVo datum : list) {
                // 开始分捡后的下一道工序
                QueryWrapper<ApsWorkDetail> query1 = Wrappers.query();
                query1.eq("aps_work_order_id", datum.getApsWorkOrderId());
                query1.gt("phase_seq", datum.getPhaseSeq());
                Integer minPhaseSeq = apsWorkDetailMapper.minPhaseSeq(query1);
                if (minPhaseSeq != null) {
                    ApsWorkDetail nextList = apsWorkDetailMapper.lambdaQuery()
                            .eq(ApsWorkDetail::getApsWorkOrderId, datum.getApsWorkOrderId())
                            .eq(ApsWorkDetail::getPhaseSeq, minPhaseSeq)
                            .orderByAsc(ApsWorkDetail::getPhaseSeq)
                            .last(" limit 1")
                            .one();

                    if (nextList != null) {
                        datum.setNextGroupCode(nextList.getGroupCode());
                        datum.setNextPhaseCode(nextList.getPhaseCode());
                    }
                }
            }
            resVo = new BasePageResVo<>(assemblList.size(), list);

        }


        return resVo;
    }

    public List<WaitWorkAsseVo> findAsseWorks(Integer groupId, List<String> plmId) {
        String assStr = plmId.stream().collect(Collectors.joining("', '", "'", "'"));

        List<WaitWorkAsseVo> wait2or3AsseWorks = workDetailTaskMapper.getAllAsseWorks1(assStr, groupId);


        List<String> collect = wait2or3AsseWorks.stream().map(WaitWorkAsseVo::getConstructNo).distinct().collect(Collectors.toList());

        Map<String, List<PoolItemVo>> poolMap = new HashMap<>();
        Map<Integer, List<PoolItemVo>> poolIdMap = new HashMap<>();
        if(CollUtil.isNotEmpty(collect)){
            String join = String.join("', '", collect);
            List<PoolItemVo> l = partMapper.selectPoolItem(join);
            poolIdMap = l.stream().collect(Collectors.groupingBy(PoolItemVo::getPoolId));

            List<PoolItemVo> collect2 = poolIdMap.values().stream().flatMap(Collection::stream).collect(Collectors.toList());

            for (PoolItemVo poolItemVo : collect2) {
                poolMap.put(poolItemVo.getConstructNo(), poolIdMap.get(poolItemVo.getPoolId()));
            }
        }

        List<Part> list = new ArrayList<>();
        LambdaQueryChainWrapper<Part> partLambdaQueryChainWrapper = partMapper.lambdaQuery();

        for (WaitWorkAsseVo wait2or3AsseWork : wait2or3AsseWorks) {
            partLambdaQueryChainWrapper.or(wr -> {
                wr.eq(Part::getPlmId, wait2or3AsseWork.getPlmId());
                wr.eq(Part::getPhaseCode, "KJ");
            });
            list = partLambdaQueryChainWrapper.list();
        }

        Map<String, Map<String, Part>> collect1 = list.stream().filter(e->e.getDeleted().equals(0)).collect(Collectors.groupingBy(Part::getPlmId, Collectors.toMap(Part::getConstructNo, e -> e)));
        for (WaitWorkAsseVo wait2or3AsseWork : wait2or3AsseWorks) {
            Map<String, Part> stringPartMap = collect1.getOrDefault(wait2or3AsseWork.getPlmId(), new HashMap<>());

            List<PoolItemVo> poolItemVos = poolMap.get(wait2or3AsseWork.getConstructNo());
            if(CollUtil.isEmpty(poolItemVos)){
                Part part = stringPartMap.get(wait2or3AsseWork.getConstructNo());
                if(part == null){
                    wait2or3AsseWork.setTotalCount(BigDecimal.ZERO);
                } else {
                    wait2or3AsseWork.setTotalCount(new BigDecimal(part.getPartCount()));
                }
            } else {
                int ct = 0;
                for (PoolItemVo poolItemVo : poolItemVos) {
                    Part part = stringPartMap.get(poolItemVo.getConstructNo());
                    if(part != null){
                        ct += part.getPartCount();

                    }
                }
                wait2or3AsseWork.setTotalCount(new BigDecimal(ct));
            }

            wait2or3AsseWork.setTotalCount(wait2or3AsseWork.getTotalCount().divide(wait2or3AsseWork.getPartCount(), 0, RoundingMode.DOWN));
        }

        Map<String, WaitWorkAsseVo> collect2 = wait2or3AsseWorks.stream().collect(Collectors.toMap(e->e.getOrderId() + "##" + e.getAssemblyNumber(), e -> e, (e1, e2)->{
            if(e1.getTotalCount().intValue() < e2.getTotalCount().intValue()){
                return e1;
            }
            return e2;
        }));

        List<WaitWorkAsseVo> l = new ArrayList<>(collect2.values());

        List<String> collect5 = l.stream().map(WaitWorkAsseVo::getConstructNo).distinct().collect(Collectors.toList());
        for (Map.Entry<Integer, List<PoolItemVo>> integerListEntry : poolIdMap.entrySet()) {
            List<PoolItemVo> value = integerListEntry.getValue();
            value = value.stream().sorted(Comparator.comparing(PoolItemVo::getSeq)).collect(Collectors.toList());
            List<Integer> collect4 = value.stream().map(PoolItemVo::getSeq).distinct().collect(Collectors.toList());
            if(collect4.size() == 1){
                continue;
            }

            boolean delFlag = false;

            for (PoolItemVo poolItemVo : value) {
                boolean contains = collect5.contains(poolItemVo.getConstructNo());
                if (!delFlag && contains) {
                    delFlag = true;
                } else if (delFlag) {
                    l.removeIf(e -> e.getConstructNo().equals(poolItemVo.getConstructNo()));
                }
            }

        }

        List<WaitWorkAsseVo> asseVoList = l.stream()
                .filter(e -> e.getTotalCount().intValue() > 0)
                .sorted(Comparator.comparing(WaitWorkAsseVo::getConstructNo).thenComparing(WaitWorkAsseVo::getOrderId).thenComparing(WaitWorkAsseVo::getAssemblyNumber))
                .collect(Collectors.toList());


        return asseVoList;
    }

    public BaseListResVo<WorkshopPlatePartResVo> platePart(BaseIdReqVo reqVo) {
        QueryWrapper<SinoCamReceiveNestPart> query = Wrappers.query();
        query.eq("t1.deleted", 0);
        query.eq("t2.deleted", 0);
        query.eq("t3.deleted", 0);
        query.eq("t4.deleted", 0);
        query.eq("t5.deleted", 0);
        query.in("t2.id", reqVo.getId());
        List<WorkshopPlatePartResVo> partList = sinoCamReceiveNestPartMapper.listPlatePart(query);
        return new BaseListResVo<>(partList);
    }

    public BaseListResVo<WorkshopComponentPartResVo> componentPart(BaseIdReqVo reqVo) {
        QueryWrapper<ApsWorkOrder> query = Wrappers.query();
        query.eq("t1.deleted", 0);
        query.eq("t2.deleted", 0);
        query.eq("t3.deleted", 0);
        query.eq("t4.deleted", 0);
        query.in("t4.id", reqVo.getId());
        query.orderByAsc("t4.aps_order_id", "t4.plan_start_date_time");
        List<WorkshopComponentPartResVo> partList = apsWorkOrderMapper.listComponentPart(query);
        return new BaseListResVo<>(partList);
    }

    /**
     * pda  装配  通过前道工序进行装盘
     *
     * @param reqVo
     */
    @Transactional
    public void packPart(WorkshopPackPartReqVo reqVo) {

        Part part = partService.getPart(null,  /* reqVo.getConstructNo()*/ null, reqVo.getPlmid(), reqVo.getPhaseCode(), reqVo.getPrePhaseCode());
        if (part == null) {
            throw SyExceptionUtils.e("无此零件{}工序{}上道工序{}", reqVo.getPlmid(), reqVo.getPhaseCode(), reqVo.getPrePhaseCode());

        }

        OrderBom one = orderBomMapper.lambdaQuery().eq(OrderBom::getPlmId, reqVo.getPlmid()).orderByDesc(OrderBom::getId).last(" limit 1").one();
        if(one.getMaterType().equals("Platepart")) {
            // 如果是零件，装盘的数量是前序的总报工数量之和，如果如果没有前序。如果没有前序，则为所有施工号的在制品之和
            List<PartPallet> partPalletList = partPalletMapper.lambdaQuery()
                    .eq(PartPallet::getPlmId, reqVo.getPlmid())
                    .eq(PartPallet::getPhaseCode, part.getPhaseCode())
                    .list();

            List<Order> orderList = orderMapper.lambdaQuery()
                    .in(Order::getOrderType, 1, 3, 4)
                    .in(Order::getOrderStatus, 6, 7, 8)
                    .list();
            List<Integer> orderIdList = orderList.stream().map(BaseEntity::getId).distinct().collect(Collectors.toList());
            List<ApsWorkDetail> awdList = apsWorkDetailMapper.lambdaQuery()
                    .in(ApsWorkDetail::getOrderId, orderIdList)
                    .eq(ApsWorkDetail::getPlmId, reqVo.getPlmid())
                    .eq(ApsWorkDetail::getPhaseCode, reqVo.getPrePhaseCode())
                    .list();

            int palletSum = partPalletList.stream().mapToInt(PartPallet::getPartCount).sum();
            int finishSum = awdList.stream().mapToInt(e -> e.getFinishCount().intValue()).sum();
            if(palletSum + reqVo.getPartCount() > finishSum){
                throw SyExceptionUtils.e("前序报工数量【{}】不足，托盘数量【{}】，此次装盘数量【{}】", finishSum, palletSum, reqVo.getPartCount());
            }

        } else {

            List<Part> partList = partMapper.lambdaQuery()
                    .eq(Part::getPhaseCode, part.getPhaseCode())
                    .eq(Part::getPlmId, reqVo.getPlmid())
                    .list();

            // 如果不是零件，就为所有的在制品之和
            List<PartPallet> partPalletList = partPalletMapper.lambdaQuery()
                    .eq(PartPallet::getPlmId, reqVo.getPlmid())
                    .eq(PartPallet::getPhaseCode, part.getPhaseCode())
                    .list();

            int partSum = partList.stream().mapToInt(Part::getPartCount).sum();
            int partPalletSum = partPalletList.stream().mapToInt(PartPallet::getPartCount).sum();
            if (partSum - reqVo.getPartCount() < partPalletSum) {
                throw SyExceptionUtils.e("在制品数量【{}】不足，托盘数量【{}】，此次装盘数量【{}】", partSum, partPalletSum, reqVo.getPartCount());
            }

        }

        /*
        if (WorkshopProp.FJ_PHASE_CODE.equalsIgnoreCase(part.getPrePhaseCode())) {
            // 分拣后的零件   控制零件数量
            List<PartPallet> ppList = partPalletMapper.lambdaQuery()
                    .eq(PartPallet::getPlmId, part.getPlmId())
                    .eq(PartPallet::getPhaseCode, part.getPhaseCode())
//                    .eq(StringUtils.hasText(reqVo.getConstructNo()), PartPallet::getConstructNo, reqVo.getConstructNo())
                    .list();
//            int palletSum = ppList.stream().filter(k -> StringUtils.hasText(k.getPositionCode()) && !k.getPositionCode().startsWith("24")).mapToInt(PartPallet::getPartCount).sum();
            int palletSum = ppList.stream().mapToInt(PartPallet::getPartCount).sum();

            List<Part> partList = partMapper.lambdaQuery()
                    .eq(Part::getPlmId, reqVo.getPlmid())
                    .eq(Part::getPhaseCode, part.getPhaseCode())
//                    .eq(StringUtils.hasText(reqVo.getConstructNo()), Part::getConstructNo, reqVo.getConstructNo())
                    .list();
            int allCount = partList.stream().mapToInt(Part::getPartCount).sum();

            if (allCount < palletSum + reqVo.getPartCount()) {
                //装盘的数量大余1小时内清空的数量
                if (reqVo.getPartCount() > partUtilService.reportClearCount(part.getPlmId(), part.getPhaseCode())) {
                    throw SyExceptionUtils.e("{}零件数量不足,零件的装配数量大于散落的数量：", part.getPlmId());
                }
            }
        }
         */

        partUtilService.putPallet(reqVo.getPartCount(), reqVo.getPalletNumber(), part);
    }


    @Transactional
    public void plateStartWorkNew(WorkshopPlateStartWorkReqVo reqVo) {
        String staffCode = stationService.getStaffCode(reqVo.getStaffCode(), reqVo.getStationCode());
        if (StringUtils.hasText(staffCode)) {
            reqVo.setStaffCode(staffCode);
        }
        String constructNo = null;

        // 找到钢板,并且更新状态
        Plate plate = plateMapper.lambdaQuery().eq(Plate::getMaterCode, reqVo.getPlateCode()).one();
        List<Integer> processStatus = Lists.newArrayList(4, 5);
        if (!processStatus.contains(plate.getStatus())) {
            throw SyExceptionUtils.e("{}不是已出库的钢板无法开工", reqVo.getPlateCode());
        }
        if (plate.getStatus() == 4) {
            plate.setStatus(5);
            plateMapper.updateById(plate);
        }
        ApsWorkDetail plateApsWorkDetail = apsWorkDetailMapper.lambdaQuery()
                .eq(ApsWorkDetail::getMaterNo, reqVo.getPlateCode())
                .eq(ApsWorkDetail::getPhaseCode, reqVo.getPhaseCode())
                .one();

        if (plateApsWorkDetail != null) {
            if (plateApsWorkDetail.getStatus() == 3) {
                throw SyExceptionUtils.e("钢板{}，工序{}已开工，禁止重复开工", reqVo.getPlateCode(), reqVo.getPhaseCode());
            }
            plateApsWorkDetail.setFinishCount(new BigDecimal(0));
            plateApsWorkDetail.setActualStartDateTime(LocalDateTime.now());
            plateApsWorkDetail.setStatus(3);
            apsWorkDetailMapper.updateById(plateApsWorkDetail);
        }

        // 钢板开工通知 MES
        this.mesWorkdRecord(plateApsWorkDetail.getMaterNo(), plateApsWorkDetail.getPhaseCode(), reqVo.getStationCode(), reqVo.getStaffCode(), 1);

        // 找到钢板任务
        WorkDetailTask task = workDetailTaskMapper.lambdaQuery()
                .eq(WorkDetailTask::getType, 1)
                .le(WorkDetailTask::getStatus, 2)
                .eq(WorkDetailTask::getMaterCode, reqVo.getPlateCode())
                .eq(WorkDetailTask::getPhaseCode, reqVo.getPhaseCode())
                .one();
        if (Objects.isNull(task)) {
            throw SyExceptionUtils.e("{}未找到待开工{}的任务", reqVo.getPlateCode(), reqVo.getPhaseCode());
        }
        if (task.getStatus() == 2) {
            return;
        }
        task.setStatus(2);
        task.setApsWorkDetailId(plateApsWorkDetail.getId());
//        task.setStartStaffCode(reqVo.getStaffCode());
        task.setActualStartDateTime(LocalDateTime.now());
        task.setStationCode(reqVo.getStationCode());
        workDetailTaskMapper.updateById(task);
        partUtilService.startPartReport(task.getGroupCode(), reqVo.getStationCode(), 1, 1, plate.getNestId(), task.getPhaseCode(), plate.getMaterCode(), 1, reqVo.getStaffCode(), task.getId(), plateApsWorkDetail.getId());

        // 下面可以不用 ---------------
        // 更新出库信息
        WmsPlatePick wmsPlatePick = wmsPlatePickMapper.lambdaQuery().eq(WmsPlatePick::getPlateId, plate.getId()).eq(WmsPlatePick::getPlateState, 4).one();
        if (wmsPlatePick != null) {
            wmsPlatePick.setPlateState(5);
            wmsPlatePickMapper.updateById(wmsPlatePick);
        }
        // 找到套料信息的所有零件
        List<SinoCamReceiveNestPart> nestPartList = sinoCamReceiveNestPartMapper.lambdaQuery()
                .apply("receive_nest_id in (select receive_nest_id from tb_third_sinocam_receive_nest_plate where stock_list_no={0})", plate.getMaterCode())
                .list();

        if (WorkshopProp.FJ_PHASE_CODE.equalsIgnoreCase(reqVo.getPhaseCode())) {
            for (SinoCamReceiveNestPart nestPart : nestPartList) {
                if (!StringUtils.hasText(nestPart.getNestPlanId())) {
                    continue;
                }
                ApsWorkDetail workQgDetail = apsWorkDetailMapper.selectById(Integer.parseInt(nestPart.getNestPlanId()));
                List<ApsWorkDetail> fjList = apsWorkDetailMapper.lambdaQuery()
                        .eq(ApsWorkDetail::getApsWorkOrderId, workQgDetail.getApsWorkOrderId())
                        .eq(ApsWorkDetail::getMaterNo, nestPart.getPartId())
                        .eq(ApsWorkDetail::getPhaseCode, WorkshopProp.FJ_PHASE_CODE)
                        .list();
                for (ApsWorkDetail apsWorkDetail : fjList) {
                    if (apsWorkDetail.getProcessCount() == null) {
                        apsWorkDetail.setProcessCount(new BigDecimal(0));
                    }
                    apsWorkDetail.setStatus(3);
                    if (apsWorkDetail.getActualStartDateTime() == null) {
                        apsWorkDetail.setActualStartDateTime(LocalDateTime.now());
                    }
                    apsWorkDetailMapper.updateById(apsWorkDetail);
                }

            }
        }

        if (WorkshopProp.YC_PHASE_CODE.equalsIgnoreCase(reqVo.getPhaseCode())) {
            // 找到工单明细
            List<ApsWorkDetail> workDetailList = apsWorkDetailMapper.selectBatchIds(nestPartList.stream().map(SinoCamReceiveNestPart::getNestPlanId).collect(Collectors.toList()));

            // 找到工单
            List<ApsWorkOrder> workOrderList = apsWorkOrderMapper.selectBatchIds(workDetailList.stream().map(ApsWorkDetail::getApsWorkOrderId).distinct().collect(Collectors.toList()));

            // 找到子订单（对应的包）
            List<ApsOrder> apsOrderList = apsOrderMapper.selectBatchIds(workOrderList.stream().map(ApsWorkOrder::getApsOrderId).distinct().collect(Collectors.toList()));
            for (ApsOrder apsOrder : apsOrderList) {
                if (apsOrder.getOrderStatus() == 6 || apsOrder.getOrderStatus() == 7) {
                    apsOrder.setOrderStatus(8);
                }

                apsOrderMapper.updateById(apsOrder);
            }

            // 找到订单
            List<Order> orderList = orderMapper.selectBatchIds(workOrderList.stream().map(ApsWorkOrder::getOrderId).distinct().collect(Collectors.toList()));
            for (Order order : orderList) {
                if (!StringUtils.hasText(constructNo)) {
                    constructNo = order.getConstructNo();
                }
                if (order.getOrderStatus() == 6 || order.getOrderStatus() == 7) {
                    order.setOrderStatus(8); // 修改订单状态 6.已发布 7.套料中 8.已开工 9.订单完成
                    order.setActualStartDateTime(LocalDateTime.now());
                }
                orderMapper.updateById(order);
            }
        }

        // 通知QMS_SY生成质检任务
        apsInformQmsService.plateStartWork(reqVo.getPlateCode(), plate.getNestId(), reqVo.getPhaseCode(), reqVo.getStationCode(), reqVo.getStaffCode());

/*//  qms  钢板开工
        if (WorkshopProp.JG_PHASE_CODE.equalsIgnoreCase(reqVo.getPhaseCode()) || WorkshopProp.HG_PHASE_CODE.equalsIgnoreCase(reqVo.getPhaseCode())) {
            ApsWorkDetail apsWorkDetail1 = apsWorkDetailMapper.lambdaQuery()
                    .eq(ApsWorkDetail::getId, nestPartList.get(0).getNestPlanId())
                    .one();
            Order order1 = orderMapper.lambdaQuery().eq(Order::getId, apsWorkDetail1.getOrderId()).one();
            qmsOldApiClient.plateWorkStart(order1.getConstructNo(), reqVo.getStationCode(), reqVo.getPlateCode(), reqVo.getPhaseCode(), plate.getNestId(), reqVo.getStaffCode());

        }*/

    }


    /**
     * 钢板报工(预处理、切割、分拣报工)
     *
     * @param reqVo
     */
    @Transactional
    public void plateEndWorkNew(WorkshopPlateEndWorkReqVo reqVo) {
        String staffCode = stationService.getStaffCode(reqVo.getStaffCode(), reqVo.getStationCode());
        if (StringUtils.hasText(staffCode)) {
            reqVo.setStaffCode(staffCode);
        }
        // 找到钢板
        Plate plate = plateMapper.lambdaQuery().eq(Plate::getMaterCode, reqVo.getPlateCode()).one();
        if (plate.getStatus() != 5) {
            throw SyExceptionUtils.e("不是已出库的钢板{}无法报工", reqVo.getPlateCode());
        }
        if (plate.getNestLock() != null && plate.getNestLock() == 1) {
            throw SyExceptionUtils.e("钢板{}被套料锁定，禁止报工", reqVo.getPlateCode());
        }
        ApsWorkDetail plateApsWorkDetail = apsWorkDetailMapper.lambdaQuery()
                .eq(ApsWorkDetail::getMaterNo, reqVo.getPlateCode())
                .eq(ApsWorkDetail::getPhaseCode, reqVo.getPhaseCode())
                .one();
        if (plateApsWorkDetail != null) {
            if (plateApsWorkDetail.getStatus() >= 4) {
                throw SyExceptionUtils.e("钢板{}工序{}已完工，禁止重复报工", reqVo.getPlateCode(), reqVo.getPhaseCode());
            }
        } else {
            throw SyExceptionUtils.e("钢板{}工序{}计划未找到", reqVo.getPlateCode(), reqVo.getPhaseCode());
        }
        if(StringUtils.hasText(reqVo.getPhaseCode())&&!WorkshopProp.FJ_PHASE_CODE.equalsIgnoreCase(reqVo.getPhaseCode())){
            // 处理钢板完工信息
            plateApsWorkDetail.setStatus(4);
            plateApsWorkDetail.setFinishCount(new BigDecimal(1));
            plateApsWorkDetail.setActualEndDateTime(LocalDateTime.now());
            apsWorkDetailMapper.updateById(plateApsWorkDetail);
        }

        // 更新出库信息
        WmsPlatePick wmsPlatePick = wmsPlatePickMapper.lambdaQuery().eq(WmsPlatePick::getPlateId, plate.getId()).one();
        if (wmsPlatePick != null) {
            wmsPlatePick.setPlateState(6);
            wmsPlatePickMapper.updateById(wmsPlatePick);
        } else {
            throw SyExceptionUtils.e("钢板{}未找到领料记录", reqVo.getPlateCode());
        }

        // 钢板任务
        WorkDetailTask task = workDetailTaskMapper.lambdaQuery()
                .eq(WorkDetailTask::getMaterCode, reqVo.getPlateCode())
                .lt(WorkDetailTask::getStatus, 3)
                .eq(WorkDetailTask::getType, 1)
                .eq(WorkDetailTask::getPhaseCode, reqVo.getPhaseCode())
                .one();
        Assert.isTrue(task != null && task.getStatus() < 3, String.format("钢板:%s 工序%s已完工或未找到", reqVo.getPlateCode(), reqVo.getPhaseCode()));
        String[] split = plate.getWorkChain().split("-");//YC-JG-FJ
        int phaseIndex = Arrays.asList(split).indexOf(task.getPhaseCode());
        if (phaseIndex < 0) {
            throw SyExceptionUtils.e("{}没有该工序:{}", reqVo.getPlateCode(), task.getPhaseCode());
        }
        List<WorkRecord> recordList = workRecordMapper.lambdaQuery().eq(WorkRecord::getOperationId, task.getId()).eq(WorkRecord::getWorkType, 1)
                .eq(WorkRecord::getPlmid, task.getMaterCode()).eq(WorkRecord::getType, 1).orderByDesc(WorkRecord::getId).list();
        Integer startId = null;
        LocalDateTime startTime = null;
        if (!CollectionUtils.isEmpty(recordList)) {
            startId = recordList.get(0).getId();
            startTime = recordList.get(0).getWorkTime();
        }
        Map<String, String> map = new HashMap<>();

        //钢板分拣
        if (phaseIndex != split.length - 1) {
            //同步mes
            this.mesWorkdRecord(plateApsWorkDetail.getMaterNo(), plateApsWorkDetail.getPhaseCode(), reqVo.getStationCode(), reqVo.getStaffCode(), 2);
            task.setStatus(3);
            task.setFailCount(0);
            task.setApsWorkDetailId(plateApsWorkDetail.getId());
            task.setTotalCount(1);
            task.setFinishCount(1);
            task.setActualEndDateTime(LocalDateTime.now());
            task.setStationCode(reqVo.getStationCode());
            reqVo.setStaffCode(StringUtils.hasText(reqVo.getStaffCode()) ? reqVo.getStaffCode() : SySecurityUtils.getUserCode());
            WorkRecord workRecord = partUtilService.complatePartReport(task.getOrderCode(), task.getGroupCode(), task.getStationCode(), 1, 2, plate.getNestId(), task.getPhaseCode(),
                    reqVo.getPlateCode(), 1, 0, reqVo.getStaffCode(), task.getId(), plateApsWorkDetail.getId(), startId, startTime, reqVo.getPlateCode());


            WorkDetailTask plateTask = plateUtils.makePlateTask(plate, task, phaseIndex, split);
            task.setNextPhaseCode(plateTask.getPhaseCode());
            task.setNextGroupCode(plateTask.getGroupCode());
            workDetailTaskMapper.updateById(task);
            //钢板装盘
            Part newPart = plateUtils.plateUpdate(plate.getMaterCode(), plateTask.getPhaseCode(), plateTask.getPhaseCode(), split[phaseIndex], plate.getWorkChain(), plateTask.getGroupCode());
            plateUtils.createPartLog(workRecord, newPart.getPhaseCode(), 4, null);
            // 钢板切割报工的时候，进行切割报工
            if (org.apache.commons.lang3.StringUtils.equals(task.getPhaseCode(), WorkshopProp.HG_PHASE_CODE) || org.apache.commons.lang3.StringUtils.equals(task.getPhaseCode(), WorkshopProp.JG_PHASE_CODE)) {

                /**
                 * 判断钢板套料结果的修改时间
                 *      如果修改时间晚于接收到该套料图号的最后检查时间，则跳过
                 *      如果修改时间早于接收到该套料图号的最后检查时间，则强制更新套料结果
                 */
                SinoCamReceiveNestNest nestNest = sinoCamReceiveNestNestMapper.lambdaQuery().eq(SinoCamReceiveNestNest::getNestId, wmsPlatePick.getNestId()).one();
                SinoCamReceiveNestCheck nestCheck = sinoCamReceiveNestCheckMapper.lambdaQuery().eq(SinoCamReceiveNestCheck::getNestId, wmsPlatePick.getNestId()).orderByDesc(BaseEntity::getCreateDateTime).last(" LIMIT 1").one();
                String changeDate = nestNest.getChangeDate();
                LocalDateTime time = LocalDateTime.parse(changeDate, DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
                if (time.isBefore(nestCheck.getCreateDateTime())) {
                    sinoCamService.updatePlateNestStatusNew(wmsPlatePick.getMaterialCode(), false);
                }

                List<SinoCamReceiveNestPart> nestPartList = sinoCamReceiveNestPartMapper.lambdaQuery().eq(SinoCamReceiveNestPart::getPlateCode, reqVo.getPlateCode()).list();
                for (SinoCamReceiveNestPart nestPart : nestPartList) {

                       //  切割报工   同时只允许处理一个套料计划
                       ApsWorkDetail apsWorkDetail = apsWorkDetailMapper.lambdaQuery()
                               .eq(ApsWorkDetail::getId, nestPart.getNestPlanId())
                               .one();
                       if (!ObjectUtils.isEmpty(apsWorkDetail)) {
                          /* if(apsWorkDetail.getStatus()==4||apsWorkDetail.getTotalCount().compareTo(apsWorkDetail.getFinishCount())<=0){
                               continue;
                           }*/
                           log.info(apsWorkDetail.getId()+"修改前数据"+JsonUtils.toJsonString(apsWorkDetail));
                           apsWorkDetailMapper.lambdaUpdate().eq(ApsWorkDetail::getId, apsWorkDetail.getId())
                                   .set(ApsWorkDetail::getUniqueCode, reqVo.getPlateCode())
                                   .set(ApsWorkDetail::getActualEndDateTime, LocalDateTime.now())
                                   .set(ObjectUtils.isEmpty(apsWorkDetail.getActualStartDateTime()),ApsWorkDetail::getActualStartDateTime, LocalDateTime.now())
                                   .set(apsWorkDetail.getFinishCount().add(new BigDecimal(nestPart.getQuantity())).compareTo(apsWorkDetail.getTotalCount())>=0,ApsWorkDetail::getStatus, 4)
                                   .setSql("finish_count=finish_count+"+nestPart.getQuantity()).update();
                           if(map.get("constructNo_"+apsWorkDetail.getOrderId())==null){
                               Order one = orderMapper.lambdaQuery().eq(Order::getId, apsWorkDetail.getOrderId()).one();
                               map.put("constructNo_"+apsWorkDetail.getOrderId(),one.getConstructNo());
                           }
                           ApsWorkOrder apsWorkOrder = apsWorkOrderMapper.selectById(apsWorkDetail.getApsWorkOrderId());
                           //大与切割计划，则只创建零件
                           Part qgPart = partUtilService.createPart(map.get("constructNo_"+apsWorkDetail.getOrderId()), apsWorkDetail.getMaterNo(), apsWorkDetail.getPhaseSeq(), task.getPhaseCode(), plateTask.getPhaseCode(), plateTask.getPhaseName(), apsWorkOrder.getWorkChain(), plateTask.getNextGroupCode(), nestPart.getQuantity(), 0);
                           partUtilService.createPartLog(1, qgPart, nestPart.getQuantity(), 0, reqVo.getPlateCode(), workRecord, null);
                           this.createPartReport(map.get("constructNo_"+apsWorkDetail.getOrderId()), wmsPlatePick.getNextWorkPlace(), apsWorkDetail, task.getPhaseCode(), new BigDecimal(nestPart.getQuantity()), reqVo);
                           partUtilService.updateDetailState(apsWorkDetail.getId());

                       }else{
                           //  如果没计划的话，创建零件
                           Part qgPart =null;
                           Part nextPart = partService.getPart(null, apsWorkDetail.getMaterNo(), WorkshopProp.FJ_PHASE_CODE);
                           if(ObjectUtils.isEmpty(nextPart)){
                               qgPart = partUtilService.createPart(null, apsWorkDetail.getMaterNo(), apsWorkDetail.getPhaseSeq(), task.getPhaseCode(), plateTask.getPhaseCode(), plateTask.getPhaseName(), "", plateTask.getNextGroupCode(), nestPart.getQuantity(), 0);
                           }else{
                                qgPart = partUtilService.createPart(nextPart.getConstructNo(), apsWorkDetail.getMaterNo(), apsWorkDetail.getPhaseSeq(), task.getPhaseCode(), plateTask.getPhaseCode(), plateTask.getPhaseName(), nextPart.getWorkChain(), plateTask.getNextGroupCode(), nestPart.getQuantity(), 0);

                           }
                           partUtilService.createPartLog(1, qgPart, nestPart.getQuantity(), 0, null, workRecord, null);
                           this.createPartReport("unknown", wmsPlatePick.getNextWorkPlace(), apsWorkDetail, task.getPhaseCode(), new BigDecimal(nestPart.getQuantity()), reqVo);
                       }
                }
            }
            if (org.apache.commons.lang3.StringUtils.equals(task.getPhaseCode(), WorkshopProp.YC_PHASE_CODE)) {
                List<SinoCamReceiveNestPart> nestPartList = sinoCamReceiveNestPartMapper.lambdaQuery().eq(SinoCamReceiveNestPart::getPlateCode, reqVo.getPlateCode()).list();
                for (SinoCamReceiveNestPart nestPart : nestPartList) {
                    ApsWorkDetail qgApsWorkDetail = apsWorkDetailMapper.lambdaQuery()
                            .eq(ApsWorkDetail::getId, nestPart.getNestPlanId())
                            .one();
                    if(!ObjectUtils.isEmpty(qgApsWorkDetail)){
                        ApsWorkDetail ycWorkDetail = apsWorkDetailMapper.lambdaQuery().eq(ApsWorkDetail::getType, 2)
                                .eq(ApsWorkDetail::getApsWorkOrderId, qgApsWorkDetail.getApsWorkOrderId())
                                .eq(ApsWorkDetail::getPhaseCode, WorkshopProp.YC_PHASE_CODE).last(" LIMIT 1 ").one();
                      /*  if(ycWorkDetail.getStatus()==4||ycWorkDetail.getTotalCount().compareTo(ycWorkDetail.getFinishCount())<=0){
                            continue;
                        }*/

                        if(map.get("constructNo_"+qgApsWorkDetail.getOrderId())==null){
                            Order one = orderMapper.lambdaQuery().eq(Order::getId, qgApsWorkDetail.getOrderId()).one();
                            map.put("constructNo_"+qgApsWorkDetail.getOrderId(),one.getConstructNo());
                        }

                      if(!ObjectUtils.isEmpty(ycWorkDetail)){
                          log.info(ycWorkDetail.getId()+"修改前数据"+JsonUtils.toJsonString(ycWorkDetail));
                          apsWorkDetailMapper.lambdaUpdate().eq(ApsWorkDetail::getId, ycWorkDetail.getId())
                                  .set(ApsWorkDetail::getUniqueCode, reqVo.getPlateCode())
                                  .set(ObjectUtils.isEmpty(ycWorkDetail.getActualStartDateTime()),ApsWorkDetail::getActualStartDateTime, LocalDateTime.now())
                                  .set(ApsWorkDetail::getActualEndDateTime, LocalDateTime.now())
                                  .set(ycWorkDetail.getFinishCount().add(new BigDecimal(nestPart.getQuantity())).compareTo(ycWorkDetail.getTotalCount())>=0,ApsWorkDetail::getStatus, 4)
                                  .setSql("finish_count=finish_count+"+nestPart.getQuantity()).update();
                          partUtilService.updateDetailState(ycWorkDetail.getId());
                      }else{
                           ycWorkDetail=new ApsWorkDetail();
                           ycWorkDetail.setMaterNo(nestPart.getPartId());
                      }
                        this.createPartReport(map.get("constructNo_"+qgApsWorkDetail.getOrderId()), plateApsWorkDetail.getGroupCode(), ycWorkDetail, task.getPhaseCode(), new BigDecimal(nestPart.getQuantity()), reqVo);


                    }
                }
            }
        } else {

            // 找到套料信息的所有零件
            List<SinoCamReceiveNestPart> nestPartList = sinoCamReceiveNestPartMapper.lambdaQuery()
                    .eq(SinoCamReceiveNestPart::getPlateCode, plate.getMaterCode())
                    .orderByAsc(SinoCamReceiveNestPart::getNestPlanId)
//                    .apply("receive_nest_id in (select receive_nest_id from tb_third_sinocam_receive_nest_plate where stock_list_no={0})", plate.getMaterCode())
                    .list();
            for (SinoCamReceiveNestPart nestPart : nestPartList) {
                if (nestPart.getQuantity() <= nestPart.getSortingCount()) {
                    continue;
                }
                if (!StringUtils.hasText(nestPart.getNestPlanId())) {
                    continue;
                }

                    // 分捡之前的工序，完成
                    ApsWorkDetail workQgDetail = apsWorkDetailMapper.selectById(Integer.parseInt(nestPart.getNestPlanId()));

                    if(map.get("constructNo_"+workQgDetail.getOrderId())==null){
                        Order one = orderMapper.lambdaQuery().eq(Order::getId, workQgDetail.getOrderId()).one();
                        map.put("constructNo_"+workQgDetail.getOrderId(),one.getConstructNo());
                    }
                    ApsWorkDetail fjDetail = apsWorkDetailMapper.lambdaQuery().eq(ApsWorkDetail::getType, 2)
                            .eq(ApsWorkDetail::getApsWorkOrderId, workQgDetail.getApsWorkOrderId())
                            .eq(ApsWorkDetail::getPhaseCode, WorkshopProp.FJ_PHASE_CODE).last("LIMIT 1").one();
//
                    if (ObjectUtils.isEmpty(fjDetail)) {
                        log.error("钢板{}未找到待分拣的计划:FJ:{}", reqVo.getPlateCode(), nestPart.getPartId());
                        continue;
                    }
                    // 获取工序最小序号
                    QueryWrapper<ApsWorkDetail> query = Wrappers.query();
                    query.eq("aps_work_order_id", workQgDetail.getApsWorkOrderId());
                    query.eq("mater_no", nestPart.getPartId());
                    query.gt("phase_seq",fjDetail.getPhaseSeq());
                    query.orderByAsc("phase_seq");
                    query.last("LIMIT 1");
                    String nextPhase = apsWorkDetailMapper.nextPhase(query);
                    // ApsWorkOrder apsWorkOrder = apsWorkOrderMapper.selectById(workQgDetail.getApsWorkOrderId());
                    // 分捡，完成部分
                    ApsWorkOrder apsWorkOrder = apsWorkOrderMapper.selectById(fjDetail.getApsWorkOrderId());
                    complateAwd(apsWorkOrder, fjDetail, nextPhase, nestPart.getQuantity(), nestPart.getQuantity(), 0, nestPart, null, reqVo.getStaffCode(), reqVo.getStationCode(), reqVo.getPlateCode());
                    nestPart.setSortingCount(nestPart.getQuantity());
                    sinoCamReceiveNestPartMapper.updateById(nestPart);


            }
            nestPartList = sinoCamReceiveNestPartMapper.lambdaQuery()
                    .eq(SinoCamReceiveNestPart::getPlateCode, plate.getMaterCode())
                    .list();
            List<SinoCamReceiveNestPart> collect = nestPartList.stream().filter(e -> e.getQuantity() > e.getSortingCount()).collect(Collectors.toList());
            if (collect.isEmpty()) {
                plateApsWorkDetail.setStatus(4);
                plateApsWorkDetail.setFinishCount(new BigDecimal(1));
                plateApsWorkDetail.setActualEndDateTime(LocalDateTime.now());
                task.setStatus(3);
                task.setFailCount(0);
                task.setApsWorkDetailId(plateApsWorkDetail.getId());
                task.setTotalCount(1);
                task.setFinishCount(1);
                task.setActualEndDateTime(LocalDateTime.now());
                task.setStationCode(reqVo.getStationCode());
                plate.setStatus(6);
                plateMapper.updateById(plate);
                reqVo.setStaffCode(StringUtils.hasText(reqVo.getStaffCode()) ? reqVo.getStaffCode() : SySecurityUtils.getUserCode());
                WorkRecord workRecord = partUtilService.complatePartReport(task.getOrderCode(), task.getGroupCode(), task.getStationCode(), 1, 2, plate.getNestId(), task.getPhaseCode(),
                        reqVo.getPlateCode(), 1, 0, reqVo.getStaffCode(), task.getId(), plateApsWorkDetail.getId(), startId, startTime, reqVo.getPlateCode());

                // 清除钢板零件表的信息
                plateUtils.clearPlate(reqVo.getPlateCode());
                plateUtils.createPartLog(workRecord, null, 3, null);
                apsWorkDetailMapper.updateById(plateApsWorkDetail);
                workDetailTaskMapper.updateById(task);
            }


        }

        // 通知QMS创建钢板上零件明细
        apsInformQmsService.plateEndWork(reqVo.getPlateCode(), reqVo.getPhaseCode());

        /*if (org.apache.commons.lang3.StringUtils.equals(task.getPhaseCode(), WorkshopProp.HG_PHASE_CODE) || org.apache.commons.lang3.StringUtils.equals(task.getPhaseCode(), WorkshopProp.JG_PHASE_CODE)) {
            Iterator<String> iterator = map.keySet().iterator();
            if (iterator.hasNext()) {
                String firstKey = iterator.next();
                qmsOldApiClient.plateWorkEnd(map.get(firstKey), reqVo.getStationCode(), reqVo.getPlateCode(), reqVo.getPhaseCode(), plate.getNestId(), reqVo.getStaffCode());
            }
        }*/

    }

    /**
     * 预处理  切割  增加零件任务信息
     *
     * @param apsWorkDetail
     * @param phaseCode
     * @param totalCount
     * @param reqVo
     */
    private void createPartReport(String constructNo, String groupCode, ApsWorkDetail apsWorkDetail, String phaseCode, BigDecimal totalCount, WorkshopPlateEndWorkReqVo reqVo) {
      /*  WorkDetailTask partTask = new WorkDetailTask();
        partTask.setPhaseCode(phaseCode);
        partTask.setPhaseName(phaseCode);
        partTask.setGroupCode(apsWorkDetail.getGroupCode());
        partTask.setType(2);
        partTask.setPlmid(apsWorkDetail.getMaterNo());
        partTask.setFailCount(0);
        partTask.setTotalCount(apsWorkDetail.getTotalCount().intValue());
        partTask.setFinishCount(apsWorkDetail.getFinishCount().intValue());
        partTask.setMaterCode(reqVo.getPlateCode());
        partTask.setMaterName(apsWorkDetail.getMaterName());
        partTask.setStatus(3);
        partTask.setPlanStartDateTime(apsWorkDetail.getPlanStartDateTime());
        partTask.setPlanEndDateTime(apsWorkDetail.getPlanEndDateTime());
        partTask.setActualStartDateTime(LocalDateTime.now());
        partTask.setActualEndDateTime(LocalDateTime.now());
        partTask.setApsWorkDetailId(apsWorkDetail.getId());
        workDetailTaskMapper.insert(partTask);*/
//        ApsOrder apsOrder = apsOrderMapper.selectById(apsWorkDetail.getApsOrderId());
        reqVo.setStaffCode(StringUtils.hasText(reqVo.getStaffCode()) ? reqVo.getStaffCode() : SySecurityUtils.getUserCode());
        partUtilService.complatePartReport(constructNo, groupCode, reqVo.getStationCode(), 2, 2,
                apsWorkDetail.getMaterNo(), phaseCode, reqVo.getPlateCode(), totalCount.intValue(), 0,
                reqVo.getStaffCode(), null, apsWorkDetail.getId(), null, null, reqVo.getPlateCode());

    }


    @Transactional
    public void mbdPpJob(LocalDate day1, String plmid, String constructNo) {

        QueryWrapper<ApsWorkDetail> wrapper = Wrappers.query();
        if (day1 != null) {
            LocalDate day = day1.plusDays(1);
            // 1。取得第二天所有PZ的数量
            wrapper.ge("wd.plan_start_date_time", day.atStartOfDay().format(DatePattern.NORM_DATETIME_FORMATTER));
            wrapper.lt("wd.plan_start_date_time", day.plusDays(1).atStartOfDay().format(DatePattern.NORM_DATETIME_FORMATTER));
        } else if (StringUtils.hasText(constructNo)) {
            wrapper.eq("tbo.construct_no", constructNo);
            wrapper.and(wd -> {
                wd.eq("wd.plm_id", plmid);
                wd.or();
                wd.eq("wd.plm_id", plmid + "_170");
            });

        } else if (StringUtils.hasText(plmid)) {
            wrapper.lt("wd.plan_start_date_time", LocalDate.now().plusDays(1).atStartOfDay().format(DatePattern.NORM_DATETIME_FORMATTER));
            wrapper.and(wd -> {
                wd.eq("wd.plm_id", plmid);
                wd.or();
                wd.eq("wd.plm_id", plmid + "_170");
            });
        }

        wrapper.in("wd.phase_code", WorkshopProp.PZ_PHASE_CODE, WorkshopProp.XH_PHASE_CODE);
        List<ApsWorkDetail> pzList = apsWorkDetailMapper.selectPpWorkDetail(wrapper);

        log.info("pzList:{}", JsonUtils.toJsonString(pzList));
        if (CollUtil.isEmpty(pzList)) {
            return;
        }

        List<String> drawIdList = pzList.stream().map(e -> e.getMaterNo().replace("_170", "")).distinct().collect(Collectors.toList());
        MatchFindPalletReqDto reqDto = new MatchFindPalletReqDto();
        reqDto.setPlmIds(drawIdList);
        log.info("请求 - mom-srv-mbd,方法:findPallet, 参数:{}", JsonUtils.toJsonString(reqDto));
        List<MatchFindPalletResDto> pallet = momSrvMbdApiClient.findPallet(reqDto);
        log.info("响应 - mom-srv-mbd,方法:findPallet, 返回值:{}", JsonUtils.toJsonString(pallet));

        List<MatchFindPartReqDto> reqDtoList = pallet.stream()
                .map(e -> {
                    MatchFindPartReqDto r = new MatchFindPartReqDto();
                    r.setPlmId(e.getPlmId());
                    r.setPalletDrawCode(e.getPalletDrawCode());
                    return r;
                })
                .collect(Collectors.toList());

        List<MatchFindPartResDto> all = new ArrayList<>();
        for (MatchFindPartReqDto matchFindPartReqDto : reqDtoList) {
            List<MatchFindPartResDto> part = momSrvMbdApiClient.findPart(matchFindPartReqDto);
            all.addAll(part);
        }
        //  组件plmid   配盘图片
        Map<String, Map<String, List<MatchFindPartResDto>>> collect2 = all.stream().collect(
                Collectors.groupingBy(MatchFindPartResDto::getComponentPlmId,
                        Collectors.groupingBy(MatchFindPartResDto::getMatchCode)
                )
        );


        Map<String, List<MatchFindPalletResDto>> plmIdMap = pallet.stream().collect(Collectors.groupingBy(MatchFindPalletResDto::getPlmId));

        List<MatchTask> ll = new ArrayList<>();
        //  将拼装计划  转换为任务列表
        for (ApsWorkDetail apsWorkDetail : pzList) {
//            ApsWorkOrder apsWorkOrder = apsWorkOrderMap.get(apsWorkDetail.getApsWorkOrderId());
//            OrderBom orderBom = drawingMap.get(apsWorkOrder.getBomId());

            MatchTask matchTask = new MatchTask();
            matchTask.setOrderId(apsWorkDetail.getOrderId());
            matchTask.setDrawingCode(apsWorkDetail.getMaterNo().replace("_170", ""));
            matchTask.setPlmId(apsWorkDetail.getMaterNo());
            matchTask.setMaterName(apsWorkDetail.getMaterName());
            matchTask.setMatchDate(apsWorkDetail.getPlanStartDateTime().toLocalDate());
            matchTask.setTotalCount(apsWorkDetail.getTotalCount().intValue());
            ll.add(matchTask);
        }

        Map<LocalDate, List<MatchTask>> collect = ll.stream().collect(Collectors.groupingBy(MatchTask::getMatchDate));
        List<LocalDate> localDates = new ArrayList<>(collect.keySet());
        Collections.sort(localDates);
        for (LocalDate localDate : localDates) {
            List<MatchTask> matchTasks = collect.get(localDate);

            //  按设计图进行分组
            Map<String, List<MatchTask>> collect1 = matchTasks.stream().collect(Collectors.groupingBy(MatchTask::getDrawingCode));
            for (String drawing : collect1.keySet()) {
                //  获取设计图下的所有配盘图
                List<MatchFindPalletResDto> matchFindPalletResDtos = plmIdMap.get(drawing);
                if (CollUtil.isEmpty(matchFindPalletResDtos)) {
                    log.info("{}缺少配盘图详情 " ,  drawing);
//                    MkErrorUtils.addError(1, localDate, drawing);
                    continue;
                }
                for (MatchFindPalletResDto matchFindPalletResDto : matchFindPalletResDtos) {
                    Integer makeCount = matchTaskMapper.lambdaQuery()
                            .eq(MatchTask::getMatchCode, matchFindPalletResDto.getPalletDrawCode())
                            .eq(MatchTask::getOrderId, collect1.get(drawing).get(0).getOrderId())
                            .list()
                            .stream()
                            .map(MatchTask::getTotalCount)
                            .reduce(0, Integer::sum);
                    BigDecimal orderCount = apsWorkOrderMapper.lambdaQuery()
                            .eq(ApsWorkOrder::getOrderId, collect1.get(drawing).get(0).getOrderId())
                            .eq(ApsWorkOrder::getPlmId, collect1.get(drawing).get(0).getPlmId())
                            .list()
                            .stream()
                            .map(ApsWorkOrder::getOrderCount)
                            .reduce(new BigDecimal(0), (a, b) -> b.add(a));
                    Integer currCount = collect1.get(drawing).stream().map(MatchTask::getTotalCount).reduce(0, Integer::sum);
                    if (orderCount.intValue() <= makeCount) {
                        continue;
                    }
                    if (orderCount.intValue() <= makeCount + currCount) {
                        currCount = orderCount.intValue() - makeCount;
                        if (currCount == 0) {
                            continue;
                        }
                    }
                    MatchTask matchTask = new MatchTask();
                    matchTask.setMaterName(collect1.get(drawing).get(0).getMaterName());
                    matchTask.setPlmId(collect1.get(drawing).get(0).getPlmId());
                    matchTask.setOrderId(collect1.get(drawing).get(0).getOrderId());
                    matchTask.setDrawingCode(drawing);
                    matchTask.setTotalCount(currCount);
                    matchTask.setFinishCount(0);
                    matchTask.setMatchDate(localDate);
                    matchTask.setStatus(1);
                    matchTask.setMatchCode(matchFindPalletResDto.getPalletDrawCode());
                    matchTask.setDrawingUrl(matchFindPalletResDto.getDrawingUrl());
                    matchTaskMapper.insert(matchTask);

                    List<MatchFindPartResDto> matchFindPartResDtos = collect2.getOrDefault(drawing, new HashMap<>()).get(matchFindPalletResDto.getPalletDrawCode());
                    if (CollUtil.isEmpty(matchFindPartResDtos)) {
                        log.info("{}缺少配盘任务零件详情 ", drawing);
                        continue;
                    }

                    for (MatchFindPartResDto matchFindPartResDto : matchFindPartResDtos) {
                        MatchDetailTask td = new MatchDetailTask();
                        td.setMatchTaskId(matchTask.getId());
                        td.setOrderId(matchTask.getOrderId());
                        td.setDrawingCode(matchFindPartResDto.getComponentPlmId());
                        td.setTotalCount(matchTask.getTotalCount() * matchFindPartResDto.getTotalCount().intValue());
                        td.setFinishCount(0);
                        td.setMaterCode(matchFindPartResDto.getMaterCode() + "_170");
                        td.setMaterName(matchFindPartResDto.getMaterName());
                        td.setStatus(1);
                        td.setQuantity(matchFindPartResDto.getTotalCount().intValue());
                        td.setMatchDate(matchTask.getMatchDate());
                        td.setMatchCode(matchTask.getMatchCode());
                        matchDetailTaskMapper.insert(td);
                    }
                }
            }
        }


    }

    public BaseListResVo<WorkShopMatchListResVo> matchList(WorkShopMatchListReqVo reqVo) {
        LambdaQueryWrapper<MatchTask> query = lambdaQuery();
        if (reqVo.getState() == 1) {
            query.eq(MatchTask::getMatchDate, LocalDate.now());
        } else {
            query.lt(MatchTask::getStatus, 3);
            query.last(" limit 200");
            query.orderByAsc(MatchTask::getMatchDate);
        }
        List<MatchTask> matchTasks = matchTaskMapper.selectList(query);
        return BaseListResVo.of(matchTasks, WorkShopMatchListResVo.class);

    }

    @Transactional
    public void matchStartWork(WorkShopMatchStartWorkReqVo reqVo) {
        // 1。设置任务状态
        MatchTask matchTask = matchTaskMapper.selectById(reqVo.getId());
        if (matchTask == null) {
            throw SyExceptionUtils.e("任务不存在");
        }
        if (matchTask.getStatus() != 1) {
            throw SyExceptionUtils.e("任务已开工");
        }
        matchTask.setStatus(2);
        matchTask.setModifyUsername(reqVo.getStationCode());
        matchTaskMapper.updateById(matchTask);

        Group group = groupMapper.selectById(reqVo.getGroupId());

        // 2。添加开报工日志
        partUtilService.startPartReport(group.getMyCode(), reqVo.getStationCode(), 1, 1,
                matchTask.getMatchCode(), WorkshopProp.PP_PHASE_CODE, null, 1, reqVo.getStaffCode(), null, null);


        // 3。零件落入工位
        Station station = stationMapper.lambdaQuery().eq(Station::getMyCode, reqVo.getStationCode()).one();
        List<Position> positionList = positionMapper.lambdaQuery().eq(Position::getStationId, station.getId()).list();

        // 清空托盘到工位
        List<String> tuopanList = positionList.stream().map(Position::getMyCode).distinct().collect(Collectors.toList());
        List<PartPallet> list = partPalletMapper.lambdaQuery()
                .in(PartPallet::getPositionCode, tuopanList)
                .list();
        for (PartPallet partPallet : list) {
            partUtilService.putPartToStation(partPallet, station.getMyCode());
        }


    }

    /**
     * 页面配盘报工
     *
     * @param reqVo
     */
    /*@Transactional
    public void matchEndWork(WorkShopMatchEndWorkReqVo reqVo) {
        // 报工检查
        if (reqVo.getQuantity() == null || reqVo.getQuantity() < 1) {
            throw SyExceptionUtils.e("报工数量不能小于1");
        }

        // 1。输入数量
        MatchTask matchTask = matchTaskMapper.selectById(reqVo.getId());
        if ((matchTask.getTotalCount() - matchTask.getFinishCount()) < reqVo.getQuantity()) {
            throw SyExceptionUtils.e("报工数量不能大于剩余数量");
        }

        Group group = groupMapper.selectById(reqVo.getGroupId());
        List<WorkRecord> recordList = workRecordMapper.lambdaQuery().eq(WorkRecord::getOperationId, matchTask.getId()).eq(WorkRecord::getWorkType, 1)
                .eq(WorkRecord::getPlmid, matchTask.getMatchCode()).eq(WorkRecord::getType, 2).orderByDesc(WorkRecord::getId).list();
        Integer startId = null;
        LocalDateTime startTime = null;
        if (!CollectionUtils.isEmpty(recordList)) {
            startId = recordList.get(0).getId();
            startTime = recordList.get(0).getWorkTime();
        }

        partUtilService.complatePartReport(null, group.getMyCode(), reqVo.getStationCode(), 2, 2,
                matchTask.getMatchCode(), WorkshopProp.PP_PHASE_CODE, null, reqVo.getQuantity(), 0, reqVo.getStaffCode(), null, null, startId, startTime, null);

        // 找到配盘列表
        MatchFindPartReqDto reqDto = new MatchFindPartReqDto();
        reqDto.setPlmId(matchTask.getDrawingCode());
        reqDto.setPalletDrawCode(matchTask.getMatchCode());
        List<MatchFindPartResDto> partList = momSrvMbdApiClient.findPart(reqDto);

        // 查工位上的零件
        List<PartPallet> pp = partPalletMapper.lambdaQuery()
                .in(PartPallet::getPlmId, partList.stream().map(MatchFindPartResDto::getMaterCode).collect(Collectors.toList()))
                .eq(PartPallet::getPhaseCode, WorkshopProp.KJ_PHASE_CODE)
                .eq(PartPallet::getType, 3)
                .eq(PartPallet::getPositionCode, reqVo.getStationCode())
                .list();

        Map<String, PartPallet> ppMap = pp.stream().collect(Collectors.toMap(PartPallet::getPlmId, Function.identity()));

        Integer quantity = reqVo.getQuantity();
        for (MatchFindPartResDto partItem : partList) {
            PartPallet partPallet = ppMap.get(partItem.getMaterCode());

            // 数据校验
            if (partPallet == null) {
                throw SyExceptionUtils.e("工位上没有该零件{}", partItem.getMaterCode());
            }

            if (partPallet.getPartCount() < quantity * partItem.getTotalCount().intValue()) {
                throw SyExceptionUtils.e("工位上的零件数量不足{}", partItem.getMaterCode());
            }

            partUtilService.reducePartFromPallet(partPallet, quantity * partItem.getTotalCount().intValue(), true);


            // 托盘零件添加
            PartPallet newPP = partPalletMapper.lambdaQuery()
                    .eq(PartPallet::getPlmId, partPallet.getPlmId())
                    .eq(PartPallet::getPhaseCode, partPallet.getPhaseCode())
                    .eq(PartPallet::getPositionCode, reqVo.getStationCode())
                    .eq(PartPallet::getType, 1)
                    .one();
            partUtilService.putPartToPallet(newPP, quantity * partItem.getTotalCount().intValue());

        }

        if (matchTask.getFinishCount().compareTo(matchTask.getTotalCount()) == 0) {
            matchTask.setStatus(3);
            matchTask.setModifyUsername(reqVo.getStaffCode());
            matchTaskMapper.updateById(matchTask);
        }


    }
*/
    //零件开工
    @Transactional
    public void partStartWorkNew(WorkshopPartStartWorkReqVo reqVo) {

        WorkDetailTask workDetailTask = workDetailTaskMapper.selectById(reqVo.getId());
        reqVo.setPhaseCode(workDetailTask.getPhaseCode());


        if (workDetailTask.getStatus() == 2) {
            return;
        }
        if (workDetailTask.getStatus() == 3) {
            throw SyExceptionUtils.e("{}已完工的工件不允许重复开工", reqVo.getPlmid());
        }

        partUtilService.startPartReport(workDetailTask.getGroupCode(), reqVo.getStationCode(), 2, 1,
                reqVo.getPlmid(), reqVo.getPhaseCode(), reqVo.getPalletNumber(), null, reqVo.getStaffCode(),
                workDetailTask.getId(), workDetailTask.getApsWorkDetailId());


        workDetailTask.setActualStartDateTime(LocalDateTime.now());
        workDetailTask.setStatus(2);
        workDetailTaskMapper.updateById(workDetailTask);
        ApsWorkDetail apsWorkDetail = partUtilService.updateDetailState(workDetailTask.getApsWorkDetailId());


        ApsWorkOrder apsWorkOrder = apsWorkOrderMapper.selectById(apsWorkDetail.getApsWorkOrderId());
        if (apsWorkOrder.getActualStartDateTime() == null) {
            apsWorkOrder.setActualStartDateTime(LocalDateTime.now());
            apsWorkOrderMapper.updateById(apsWorkOrder);
        }
       if(!StringUtils.isEmpty(reqVo.getStationCode())){
           stationMapper.returnToRequester(reqVo.getStationCode(), 4);
       }

        /*Order one = orderMapper.lambdaQuery().eq(Order::getId, apsWorkDetail.getOrderId()).one();
        qmsOldApiClient.partWorkStart(one.getConstructNo(), reqVo.getStationCode(), reqVo.getPlmid(), reqVo.getPhaseCode(), reqVo.getStaffCode());*/

    }

    public BasePageResVo<WorkShopPartListResVo> partList(WorkShopPartListReqVo reqVo) {
        Page<Part> list = partMapper.lambdaQuery()
                .like(StringUtils.hasText(reqVo.getPlmid()), Part::getPlmId, reqVo.getPlmid())
                .like(StringUtils.hasText(reqVo.getConstructNo()), Part::getConstructNo, reqVo.getConstructNo())
                .eq(StringUtils.hasText(reqVo.getPhaseCode()), Part::getPhaseCode, reqVo.getPhaseCode())
                .eq(StringUtils.hasText(reqVo.getPrePhaseCode()), Part::getPrePhaseCode, reqVo.getPrePhaseCode())
                .like(StringUtils.hasText(reqVo.getGroupCode()), Part::getWorkGroup, reqVo.getGroupCode())
                .page(reqVo.toPage());
        List<WorkShopPartListResVo> l = new ArrayList<>();

        for (Part part : list.getRecords()) {
            if (part.getPartType() == null || part.getPartType() == 1) {
                WorkShopPartListResVo workShopPartListResVo = new WorkShopPartListResVo();
                workShopPartListResVo.setPartCount(1);
                workShopPartListResVo.setConstructNo(part.getConstructNo());
                workShopPartListResVo.setPalletCount(0);
                workShopPartListResVo.setUnPalletCount(1);
                workShopPartListResVo.setPlmid(part.getPlmId());
                workShopPartListResVo.setPhaseCode(part.getPhaseCode());
                workShopPartListResVo.setPhaseName(part.getPhaseName());
                workShopPartListResVo.setPrePhaseCode(part.getPrePhaseCode());
                workShopPartListResVo.setGroupCode(part.getWorkGroup());
                workShopPartListResVo.setMaterName("钢板");
                l.add(workShopPartListResVo);
                Plate plate = plateMapper.lambdaQuery().eq(Plate::getMaterCode, workShopPartListResVo.getPlmid()).one();
                workShopPartListResVo.setWorkChain(plate.getWorkChain());

                PartPallet partPallet = partPalletMapper.query()
                        .select(" sum(part_count) as partCount ")
                        .eq("plm_id", part.getPlmId())
                        .eq("phase_code", part.getPhaseCode())
                        // .eq("pre_phase_code", part.getPrePhaseCode())
                        .eq("construct_no", part.getConstructNo())
                        .one();
                Integer k = 0;
                if (partPallet != null) {
                    k = partPallet.getPartCount();
                }

                workShopPartListResVo.setPalletCount(k);
                workShopPartListResVo.setUnPalletCount(workShopPartListResVo.getPartCount() - workShopPartListResVo.getPalletCount());
                continue;
            }
            OrderBom bom = orderBomMapper.lambdaQuery().eq(OrderBom::getPlmId, part.getPlmId()).last(" limit 1 ").one();

//            OrderPhase phase = orderPhaseMapper.lambdaQuery()
//                    .eq(OrderPhase::getBomId, bom.getId())
//                    .eq(OrderPhase::getPhaseCode, part.getPhaseCode())
//                    .last(" limit 1")
//                    .one();
            WorkShopPartListResVo workShopPartListResVo = MkBeanUtils.copyProperties(part, WorkShopPartListResVo.class);
            if (bom != null) {
//                log.error("bom结构异常" +part.getPlmId());
//                continue;
//
                //  SHANCHU
                workShopPartListResVo.setMaterName(bom.getMaterName());
            }
            workShopPartListResVo.setPlmid(part.getPlmId());
            workShopPartListResVo.setGroupCode(part.getWorkGroup());
            PartPallet partPallet = partPalletMapper.query()
                    .select(" sum(part_count) as partCount ")
                    .eq("plm_id", part.getPlmId())
                    .eq("phase_code", part.getPhaseCode())
//                    .eq("pre_phase_code", part.getPrePhaseCode())
                    .eq("construct_no", part.getConstructNo())
                    .one();
            Integer k = 0;
            if (partPallet != null) {
                k = partPallet.getPartCount();
            }

            workShopPartListResVo.setPalletCount(k);
            workShopPartListResVo.setUnPalletCount(workShopPartListResVo.getPartCount() - workShopPartListResVo.getPalletCount());

            l.add(workShopPartListResVo);
        }
        return new BasePageResVo<>(list.getTotal(), l);
    }


    public BaseListResVo<WorkShopPartPalletListResVo> partPalletList(WorkShopPartPalletListReqVo reqVo) {
        List<PartPallet> list = partPalletMapper.lambdaQuery()
                .eq(PartPallet::getPlmId, reqVo.getPlmid())
                .eq(PartPallet::getPhaseCode, reqVo.getPhaseCode())
                .eq(PartPallet::getPrePhaseCode, reqVo.getPrePhaseCode())
                .list();

        return BaseListResVo.of(list, WorkShopPartPalletListResVo.class);
    }

    @Transactional
    public void palletClean(PlateDelPartReqVo reqVo, boolean send) {
        if (reqVo.getId() != null) {
            PartPallet partPallet = partPalletMapper.selectById(reqVo.getId());
            partUtilService.reducePartFromPallet(partPallet, partPallet.getPartCount(), send);
        } else {

            List<PartPallet> list = partPalletMapper.lambdaQuery().eq(PartPallet::getLoadingCode, reqVo.getPalletCode()).eq(PartPallet::getPlmId, reqVo.getPlmid()).list();
            for (PartPallet partPallet : list) {
                //wms调用，不需要进行回调
                partUtilService.reducePartFromPallet(partPallet, partPallet.getPartCount(), false);
            }
        }

    }

    @Transactional
    public void partEndWorkNew(WorkshopPartEndWorkReqVo reqVo) {
        String staffCode = stationService.getStaffCode(reqVo.getStaffCode(), reqVo.getStationCode());
        if (StringUtils.hasText(staffCode)) {
            reqVo.setStaffCode(staffCode);
        }
        if (reqVo.getPartCount() == null || reqVo.getPartCount() + reqVo.getFailCount() < 1) {
            throw SyExceptionUtils.e("报工数量不能小于0");
        }
        Group group = groupMapper.selectOne(new QueryWrapper<Group>().eq("my_code", reqVo.getGroupCode()));
        if (ObjectUtils.isEmpty(group)) {
            group = groupMapper.selectGroupByWorkPlace(Wrappers.<Group>query()
                    .eq("ts.my_code", reqVo.getGroupCode()));
        }

        boolean flage = true;
        if (StringUtils.hasText(reqVo.getPhaseCode())) {
            // ||WorkshopProp.BX_PHASE_CODE.equals( reqVo.getPhaseCode())||WorkshopProp.BZ_PHASE_CODE.equals( reqVo.getPhaseCode())
            if (reqVo.getPhaseCode().contains(WorkshopProp.JP_PHASE_CODE) || reqVo.getPhaseCode().contains(WorkshopProp.PK_PHASE_CODE)) {
                PhaseGroup one = phaseGroupMapper.lambdaQuery().eq(PhaseGroup::getGroupCode, group.getMyCode()).one();
                // 同工序可以 不同工位进行报工
                if (!ObjectUtils.isEmpty(one)) {
                    flage = !reqVo.getPhaseCode().contains(one.getPhaseCode());
                }
            }
        }
       /* List<WorkDetailTask> taskList = workDetailTaskMapper.lambdaQuery()
                .eq(WorkDetailTask::getPlmid, reqVo.getPlmid())
//                .eq(WorkDetailTask::getPrePhaseCode, oldpart.getPrePhaseCode())
                .eq(StringUtils.hasText(reqVo.getPhaseCode()),WorkDetailTask::getPhaseCode, reqVo.getPhaseCode())
                .eq(flage,WorkDetailTask::getGroupCode, group.getMyCode())
                .eq(WorkDetailTask::getStatus, 2)
                .orderByAsc(WorkDetailTask::getTotalCount)
                .list();*/
        QueryWrapper<WorkDetailTask> objectQueryWrapper = new QueryWrapper<>();
        objectQueryWrapper.eq("tm.plmid", reqVo.getPlmid());
        objectQueryWrapper.eq(StringUtils.hasText(reqVo.getPhaseCode()), "tm.phase_code", reqVo.getPhaseCode());
        objectQueryWrapper.eq(flage, "tm.group_code", group.getMyCode());
        if (StringUtils.hasText(reqVo.getConstrunctNo())) {
            objectQueryWrapper.eq("tr.construct_no", reqVo.getConstrunctNo());
        }

        if(reqVo.getId() != null){
            objectQueryWrapper.eq("tm.id", reqVo.getId());
        }

        objectQueryWrapper.lt("tm.status", 3);
        objectQueryWrapper.lt("td.status", 4);
        objectQueryWrapper.eq("tm.deleted", 0);
        objectQueryWrapper.orderByAsc("td.order_id,td.aps_order_id");
        List<WorkDetailTask> taskList = workDetailTaskMapper.getTasklist(objectQueryWrapper);
        if (taskList.isEmpty()) {
            throw SyExceptionUtils.e("{}没有找到开工中的任务", reqVo.getPlmid());
        }
        if (!StringUtils.hasText(reqVo.getPhaseCode())) {
            reqVo.setPhaseCode(taskList.get(0).getPhaseCode());
        }
        ApsWorkDetail apsDetail = apsWorkDetailMapper.selectById(taskList.get(0).getApsWorkDetailId());
        ApsWorkOrder apsWorkOrder = apsWorkOrderMapper.selectById(apsDetail.getApsWorkOrderId());
        ApsOrder apsOrder = apsOrderMapper.selectById(apsDetail.getApsOrderId());
        // 直接扣除零件，不需要从托盘扣除
        Part oldpart = null;
        if (WorkshopProp.MES_PART_FLAGE.equals(reqVo.getStartPalletNumber())) {
          /*  WorkDetailTask task = null;
            if (reqVo.getId() != null) {
                //  页面访问的时候会传输任务id
                task = workDetailTaskMapper.lambdaQuery().eq(WorkDetailTask::getId, reqVo.getId()).one();
            }*/

            // 零件数据减去
            oldpart = partService.getPart(apsOrder.getConstructNo(), reqVo.getPlmid(), reqVo.getPhaseCode());

            if (oldpart == null) {
                oldpart = partService.getPart(null, reqVo.getPlmid(), reqVo.getPhaseCode());
                if (oldpart == null) {
                    throw SyExceptionUtils.e("在制品未找到零件{}工序{}", reqVo.getPlmid(), reqVo.getPhaseCode());
                }
            }
//            partUtilService.consumePart(oldpart, reqVo.getPartCount() + reqVo.getFailCount(), group.getMyCode(), reqVo.getStationCode(), null, null);

        } else {
            // 查找托盘上是否有该零件
            PartPallet partPallet = partPalletMapper.lambdaQuery()
                    .eq(PartPallet::getPlmId, reqVo.getPlmid())
                    .eq(PartPallet::getPhaseCode, reqVo.getPhaseCode())//上报的是当前工序
                    .eq(StringUtils.hasText(reqVo.getStartPalletNumber()), PartPallet::getLoadingCode, reqVo.getStartPalletNumber())
                    .eq(StringUtils.hasText(reqVo.getUniqueCode()), PartPallet::getUniqueCode, reqVo.getUniqueCode())
                    .one();

            if (partPallet == null) {
                if (StringUtils.hasText(reqVo.getStartPalletNumber()) && reqVo.getStartPalletNumber().startsWith("D")) {
                } else {
                    throw SyExceptionUtils.e("该托盘{}上没有此零件{}!", reqVo.getStartPalletNumber(), reqVo.getPlmid());
                }
            } else {
                partUtilService.reducePartFromPallet(partPallet, reqVo.getPartCount(), true);
            }
            // 零件数据减去
            oldpart = partService.getPart(apsOrder.getConstructNo(), reqVo.getPlmid(), reqVo.getPhaseCode());
            if (oldpart == null) {
                oldpart = partService.getPart(null, reqVo.getPlmid(), reqVo.getPhaseCode());
                if (oldpart == null) {
                    throw SyExceptionUtils.e("在制品未找到零件{}工序{}", reqVo.getPlmid(), reqVo.getPhaseCode());
                }
            }
//            partUtilService.consumePart(oldpart, reqVo.getPartCount() + reqVo.getFailCount(), group.getMyCode(), reqVo.getStationCode(), null, null);

        }

        List<Part> partList = partMapper.lambdaQuery().eq(Part::getPlmId, reqVo.getPlmid()).eq(Part::getPhaseCode, reqVo.getPhaseCode()).list();
        Map<String, Part> partMap = partList.stream().collect(Collectors.toMap(Part::getConstructNo, Function.identity()));

        Map<String, Integer> partCountMap = new HashMap<>();
        Map<String, Integer> failCountMap = new HashMap<>();

        ApsWorkDetail nextApsDetail = null;
        int leftReportCount = reqVo.getPartCount() + reqVo.getFailCount();
        int leftFailCount = reqVo.getFailCount();
        Integer oldApsWorkDetailId = null;
        Integer startId = null;
        LocalDateTime startTime = null;
        for (WorkDetailTask workDetailTask : taskList) {
            if (startId == null) {
                List<WorkRecord> recordList = workRecordMapper.lambdaQuery().eq(WorkRecord::getApsWorkDetailId, workDetailTask.getApsWorkDetailId()).eq(WorkRecord::getWorkType, 1)
                        .eq(WorkRecord::getPlmid, reqVo.getPlmid()).eq(WorkRecord::getType, 2).orderByDesc(WorkRecord::getId).last("LIMIT 1").list();
                if (!CollectionUtils.isEmpty(recordList)) {
                    startId = recordList.get(0).getId();
                    startTime = recordList.get(0).getWorkTime();
                    WorkRecord wr = recordList.get(0);
                    if (!StringUtils.hasText(wr.getPalletNumber())) {
                        wr.setPalletNumber(reqVo.getStartPalletNumber());
                        workRecordMapper.updateById(wr);
                    }
                }
            }

            Part part = partMap.get(workDetailTask.getConstructNo());
            if(part == null){
                throw SyExceptionUtils.e("{} 没有在制品：{}", workDetailTask.getConstructNo(), reqVo.getPlmid());
            }

            if (leftReportCount < 1) {
                break;
            }
            oldApsWorkDetailId = workDetailTask.getApsWorkDetailId();
            int currentLeftCout = workDetailTask.getTotalCount() - workDetailTask.getFinishCount() - workDetailTask.getFailCount();
            if (currentLeftCout > leftReportCount) {
                // 零件数据新增
                if (leftFailCount > 0) {
                    leftReportCount = leftReportCount - leftFailCount;
                }
                workDetailTask.setFinishCount(workDetailTask.getFinishCount() + leftReportCount);
                workDetailTask.setFailCount(workDetailTask.getFailCount() + leftFailCount);
                workDetailTask.setStatus(2);
                workDetailTask.setStationCode(reqVo.getStationCode());
                workDetailTask.setModifyUsername(reqVo.getStaffCode());
                // 回填workdetail
                nextApsDetail = updateApsDetailAndCreateTask(workDetailTask, oldpart, leftReportCount, leftFailCount, reqVo.getPalletNumber(), reqVo.getStaffCode());
                workDetailTask.setNextGroupCode(nextApsDetail.getGroupCode());
                workDetailTask.setNextPhaseCode(nextApsDetail.getPhaseCode());
                workDetailTaskMapper.updateById(workDetailTask);

                partUtilService.consumePart(part, leftReportCount +leftFailCount, group.getMyCode(), reqVo.getStationCode(), null, null);
                partCountMap.merge(part.getConstructNo(), leftReportCount, Integer::sum);
                failCountMap.merge(part.getConstructNo(), leftFailCount, Integer::sum);

                reqVo.setStaffCode(StringUtils.hasText(reqVo.getStaffCode()) ? reqVo.getStaffCode() : SySecurityUtils.getUserCode());
                partUtilService.complatePartReport(part.getConstructNo(), group.getMyCode(), reqVo.getStationCode(), 2, 2, reqVo.getPlmid(), reqVo.getPhaseCode(),
                        reqVo.getPalletNumber(), leftReportCount + leftFailCount, leftFailCount, reqVo.getStaffCode(), workDetailTask.getId(), workDetailTask.getApsWorkDetailId(), startId, startTime, null);
                leftReportCount = 0;
                leftFailCount = 0;
            } else if (currentLeftCout == 0) {
                workDetailTask.setStatus(3);
                workDetailTask.setModifyUsername(reqVo.getStaffCode());
                workDetailTaskMapper.updateById(workDetailTask);
                partUtilService.updateDetailState(workDetailTask.getApsWorkDetailId());

            } else {
                if (leftFailCount > currentLeftCout) {

                    workDetailTask.setFailCount(workDetailTask.getFailCount() + currentLeftCout);
                    workDetailTask.setStatus(3);
                    workDetailTask.setStationCode(reqVo.getStationCode());
                    workDetailTask.setModifyUsername(reqVo.getStaffCode());
                    workDetailTask.setActualEndDateTime(LocalDateTime.now());
                    nextApsDetail = updateApsDetailAndCreateTask(workDetailTask, oldpart, 0, leftFailCount, reqVo.getPalletNumber(), reqVo.getStaffCode());
                    workDetailTask.setNextGroupCode(nextApsDetail.getGroupCode());
                    workDetailTask.setNextPhaseCode(nextApsDetail.getPhaseCode());
                    workDetailTaskMapper.updateById(workDetailTask);

                    partUtilService.consumePart(part, currentLeftCout, group.getMyCode(), reqVo.getStationCode(), null, null);
                    failCountMap.merge(part.getConstructNo(), currentLeftCout, Integer::sum);

                    reqVo.setStaffCode(StringUtils.hasText(reqVo.getStaffCode()) ? reqVo.getStaffCode() : SySecurityUtils.getUserCode());
                    partUtilService.complatePartReport(part.getConstructNo(), group.getMyCode(), reqVo.getStationCode(), 2, 2, reqVo.getPlmid(), reqVo.getPhaseCode(),
                            reqVo.getPalletNumber(), leftFailCount, leftFailCount, reqVo.getStaffCode(), workDetailTask.getId(), workDetailTask.getApsWorkDetailId(), startId, startTime, null);

                    leftFailCount = leftFailCount - currentLeftCout;
                    leftReportCount = leftReportCount - currentLeftCout;

                } else {
                    workDetailTask.setFinishCount(workDetailTask.getFinishCount() + (currentLeftCout - leftFailCount));
                    workDetailTask.setFailCount(workDetailTask.getFailCount() + leftFailCount);
                    workDetailTask.setActualEndDateTime(LocalDateTime.now());
                    workDetailTask.setStatus(3);
                    workDetailTask.setStationCode(reqVo.getStationCode());
                    workDetailTask.setModifyUsername(reqVo.getStaffCode());
                    nextApsDetail = updateApsDetailAndCreateTask(workDetailTask, oldpart, currentLeftCout - leftFailCount, leftFailCount, reqVo.getPalletNumber(), reqVo.getStaffCode());

                    reqVo.setStaffCode(StringUtils.hasText(reqVo.getStaffCode()) ? reqVo.getStaffCode() : SySecurityUtils.getUserCode());

                    partUtilService.consumePart(part, currentLeftCout, group.getMyCode(), reqVo.getStationCode(), null, null);
                    partCountMap.merge(part.getConstructNo(), currentLeftCout - leftFailCount, Integer::sum);
                    failCountMap.merge(part.getConstructNo(), leftFailCount, Integer::sum);

                    partUtilService.complatePartReport(part.getConstructNo(), group.getMyCode(), reqVo.getStationCode(), 2, 2, reqVo.getPlmid(), reqVo.getPhaseCode(),
                            reqVo.getPalletNumber(), currentLeftCout, leftFailCount, reqVo.getStaffCode(), workDetailTask.getId(), workDetailTask.getApsWorkDetailId(), startId, startTime, null);
                    leftReportCount = leftReportCount - currentLeftCout;
                    leftFailCount = 0;
                    if (nextApsDetail != null) {
                        workDetailTask.setNextGroupCode(nextApsDetail.getGroupCode());
                        workDetailTask.setNextPhaseCode(nextApsDetail.getPhaseCode());
                    }
                    workDetailTaskMapper.updateById(workDetailTask);
                }
            }

        }
        if (leftReportCount > 0) {
            throw SyExceptionUtils.e(String.format("%s报工数量超过待加工的数量%s", reqVo.getPlmid(), leftReportCount));
        }
        if (!ObjectUtils.isEmpty(oldpart) && nextApsDetail != null) {
            List<String> l = new ArrayList<>();
            l.addAll(partCountMap.keySet());
            l.addAll(failCountMap.keySet());
            List<String> keys = l.stream().distinct().collect(Collectors.toList());


            for (String constructNo : keys) {
                List<PoolPart> list = poolPartMapper.lambdaQuery()
                        .eq(PoolPart::getMyCode, constructNo)
                        .eq(PoolPart::getPlmId, oldpart.getPlmId())
                        .eq(PoolPart::getPhaseCode, nextApsDetail.getPhaseCode())
                        .apply(" out_total < in_total ")
                        .list();
                if (CollUtil.isNotEmpty(list) && partCountMap.getOrDefault(constructNo, 0) > 0) {
                    int ct = partCountMap.getOrDefault(constructNo, 0);

                    for (PoolPart poolPart : list) {
                        int current = poolPart.getInTotal() - poolPart.getOutTotal();
                        if(current >= ct){
                            current = ct;
                        }
                        Part newPart = partUtilService.createPart(poolPart.getTargetCode(), oldpart.getPlmId(), oldpart.getPhaseSeq(), oldpart.getPhaseCode(), nextApsDetail.getPhaseCode(), nextApsDetail.getPhaseName(), oldpart.getWorkChain(), nextApsDetail.getGroupCode(), current, 0);
                        partExceptService.createPartExcept(poolPart.getTargetCode(), newPart.getPlmId(), newPart.getPrePhaseCode(), newPart.getPhaseCode(), newPart.getPhaseSeq(), failCountMap.getOrDefault(constructNo, 0), reqVo.getStaffCode(), oldApsWorkDetailId, group.getMyCode(), reqVo.getStationCode(), null);
                        partUtilService.createPartLog(1, newPart, current, failCountMap.getOrDefault(constructNo, 0), reqVo.getPalletNumber(), null, null);
                        if (WorkshopProp.YM_PHASE_CODE.equals(oldpart.getPhaseCode()) || WorkshopProp.ZW_PHASE_CODE.equals(oldpart.getPhaseCode())) {
                            //预埋、折弯支持多零件混放
                            partUtilService.putMultiplePallet(partCountMap.getOrDefault(constructNo, 0), reqVo.getPalletNumber(), newPart);
                        } else {
                            partUtilService.putPallet(partCountMap.getOrDefault(constructNo, 0), reqVo.getPalletNumber(), newPart);
                        }

                        ct = ct - current;
                        poolPart.setOutTotal(poolPart.getOutTotal() + current);
                        poolPartMapper.updateById(poolPart);

                        PoolLog pl = new PoolLog();
                        pl.setPoolPartId(poolPart.getId());
                        pl.setMyCode(poolPart.getMyCode());
                        pl.setTargetCode(poolPart.getTargetCode());
                        pl.setPlmId(poolPart.getPlmId());
                        pl.setPhaseCode(poolPart.getPhaseCode());
                        pl.setType(2);
                        pl.setTotal(current);
                        poolLogMapper.insert(pl);

                        if(ct == 0){
                            break;
                        }

                    }

                    if(ct > 0){
                        Part newPart = partUtilService.createPart(oldpart.getConstructNo(), oldpart.getPlmId(), oldpart.getPhaseSeq(), oldpart.getPhaseCode(), nextApsDetail.getPhaseCode(), nextApsDetail.getPhaseName(), oldpart.getWorkChain(), nextApsDetail.getGroupCode(), ct, 0);
                        partExceptService.createPartExcept(oldpart.getConstructNo(), newPart.getPlmId(), newPart.getPrePhaseCode(), newPart.getPhaseCode(), newPart.getPhaseSeq(), failCountMap.getOrDefault(constructNo, 0), reqVo.getStaffCode(), oldApsWorkDetailId, group.getMyCode(), reqVo.getStationCode(), null);
                        partUtilService.createPartLog(1, newPart, ct, failCountMap.getOrDefault(constructNo, 0), reqVo.getPalletNumber(), null, null);
                        if (WorkshopProp.YM_PHASE_CODE.equals(oldpart.getPhaseCode()) || WorkshopProp.ZW_PHASE_CODE.equals(oldpart.getPhaseCode())) {
                            //预埋、折弯支持多零件混放
                            partUtilService.putMultiplePallet(partCountMap.getOrDefault(constructNo, 0), reqVo.getPalletNumber(), newPart);
                        } else {
                            partUtilService.putPallet(partCountMap.getOrDefault(constructNo, 0), reqVo.getPalletNumber(), newPart);
                        }
                    }

                } else {
                    Part newPart = partUtilService.createPart(constructNo, oldpart.getPlmId(), oldpart.getPhaseSeq(), oldpart.getPhaseCode(), nextApsDetail.getPhaseCode(), nextApsDetail.getPhaseName(), oldpart.getWorkChain(), nextApsDetail.getGroupCode(), partCountMap.getOrDefault(constructNo, 0), failCountMap.getOrDefault(constructNo, 0));
                    partExceptService.createPartExcept(constructNo, newPart.getPlmId(), newPart.getPrePhaseCode(), newPart.getPhaseCode(), newPart.getPhaseSeq(), failCountMap.getOrDefault(constructNo, 0), reqVo.getStaffCode(), oldApsWorkDetailId, group.getMyCode(), reqVo.getStationCode(), null);
                    partUtilService.createPartLog(1, newPart, partCountMap.getOrDefault(constructNo, 0), failCountMap.getOrDefault(constructNo, 0), reqVo.getPalletNumber(), null, null);
                    if (WorkshopProp.YM_PHASE_CODE.equals(oldpart.getPhaseCode()) || WorkshopProp.ZW_PHASE_CODE.equals(oldpart.getPhaseCode())) {
                        //预埋、折弯支持多零件混放
                        partUtilService.putMultiplePallet(partCountMap.getOrDefault(constructNo, 0), reqVo.getPalletNumber(), newPart);
                    } else {
                        partUtilService.putPallet(partCountMap.getOrDefault(constructNo, 0), reqVo.getPalletNumber(), newPart);
                    }
                }


            }




        }

        BigDecimal partCount = BigDecimal.valueOf(reqVo.getPartCount());
        // 通知QMS_SY生成质检任务
        apsInformQmsService.partStartWork(reqVo.getPlmid(), apsWorkOrder.getErpCode(), apsWorkOrder.getMaterName(), partCount, apsOrder.getConstructNo(), reqVo.getPhaseCode(), reqVo.getStationCode(), reqVo.getStaffCode(), reqVo.getPalletNumber(), reqVo.getStorageNumber(), apsWorkOrder.getWorkOrderCode(), PkgUtils.gen(apsOrder.getSeq()));

//        qmsOldApiClient.partWorkEnd(apsOrder.getConstructNo(), reqVo.getStationCode(), reqVo.getPlmid(), reqVo.getPhaseCode(), reqVo.getStaffCode(), reqVo.getPartCount(), reqVo.getPalletNumber(), reqVo.getStartPalletNumber());

    }

    /**
     * 零件报工处理
     *
     * @param workDetailTask
     * @param partCount
     */
    public ApsWorkDetail updateApsDetailAndCreateTask(WorkDetailTask workDetailTask, Part oldpart, int partCount, int failCount, String palletNumber, String staffCode) {
        // 如果没有下一道工序，就待配盘，如果有则添加Task任务
//        select * from tb_mes_part mp where mp.plmid = '0177-01-0301-Z12_170' and phase_code = 'JP'
        apsWorkDetailMapper.lambdaUpdate()
                .eq(ApsWorkDetail::getId, workDetailTask.getApsWorkDetailId())
                .set(ApsWorkDetail::getUniqueCode, workDetailTask.getPlateCode())
                .set(ApsWorkDetail::getActualEndDateTime, LocalDateTime.now())
                .setSql("finish_count=finish_count+" + (partCount + failCount))
                .update();
        ApsWorkDetail awd1=partUtilService.updateDetailState(workDetailTask.getApsWorkDetailId());

        String nextPhaseCode = null;
        QueryWrapper<ApsWorkDetail> query = Wrappers.query();
        query.eq("aps_work_order_id", awd1.getApsWorkOrderId());
        query.eq("mater_no", awd1.getMaterNo());
        query.gt("phase_seq", awd1.getPhaseSeq());
        query.orderByAsc("phase_seq");
        query.last("LIMIT 1");
        String nextPhase = apsWorkDetailMapper.nextPhase(query);
        //  index  前工序    index+1当前工序      index+2 下道工序
        if (StringUtils.hasText(nextPhase) && !WorkshopProp.KJ_PHASE_CODE.equals(nextPhase)) {
            ApsWorkDetail awd = apsWorkDetailMapper.lambdaQuery()
                    .eq(ApsWorkDetail::getMaterNo, workDetailTask.getPlmid())
                    .eq(ApsWorkDetail::getPhaseCode, nextPhase)
                    .in(ApsWorkDetail::getStatus, 2, 3)
                    .eq(ApsWorkDetail::getApsWorkOrderId, awd1.getApsWorkOrderId())
                    .orderByDesc(ApsWorkDetail::getCreateDateTime)
                    .last("limit 1")
                    .one();
            if (awd != null) {
                partUtilService.makeWorkDetailTask(awd, new BigDecimal(partCount), workDetailTask, workDetailTask.getPhaseCode());
            } else {
                PartLog ph = new PartLog();
                ph.setOperationType(7);
                ph.setPartType(2);
                ph.setConstructNo(oldpart.getConstructNo());
                ph.setPartId(workDetailTask.getPlmid());
                ph.setPhaseCode(awd1.getPhaseCode());
                ph.setNextPhaseCode(nextPhase);
                ph.setSuccessCount(0);
                ph.setUniCode("任务超计划");
                ph.setErrorCount(partCount);
                ph.setTotalCount(partCount);
                ph.setAfterCount(partCount);
                ph.setReportId(awd1.getApsWorkOrderId());
                ph.setLoadType(1);
                partLogMapper.insert(ph);
            }


            return awd;
        } else {
            nextPhaseCode = WorkshopProp.KJ_PHASE_CODE;
            ApsWorkOrder apsWorkOrder = apsWorkOrderMapper.selectById(awd1.getApsWorkOrderId());
            apsWorkOrder.setFinishCount(apsWorkOrder.getFinishCount().add(new BigDecimal(partCount + failCount)));
            if (apsWorkOrder.getFinishCount().intValue() >= apsWorkOrder.getOrderCount().intValue()) {
                apsWorkOrder.setStatus(4);
            }
            apsWorkOrder.setActualEndDateTime(LocalDateTime.now());
            apsWorkOrderMapper.updateById(apsWorkOrder);


            // 判断订单顶层的五拼是否完成，完成则订单完成
            ApsWorkOrder workOrder = apsWorkOrderMapper.lambdaQuery()
                    .eq(ApsWorkOrder::getApsOrderId, apsWorkOrder.getApsOrderId())
                    .isNull(ApsWorkOrder::getPid)
                    .one();
            ApsOrder apsOrder = apsOrderMapper.selectById(apsWorkOrder.getApsOrderId());
            if (workOrder.getOrderCount().compareTo(workOrder.getFinishCount()) <= 0) {

                apsOrder.setOrderStatus(9);
                apsOrder.setActualFinishTime(LocalDateTime.now());
                apsOrderMapper.updateById(apsOrder);

                // 再判断是否所有的子订单都完成，如果
                Integer count = apsOrderMapper.lambdaQuery()
                        .eq(ApsOrder::getOrderId, apsOrder.getOrderId())
                        .ne(ApsOrder::getOrderStatus, 9)
                        .count();
                if (count == 0) {
                    Order order = orderMapper.selectById(apsOrder.getOrderId());
                    order.setOrderStatus(9);
                    order.setActualEndDateTime(LocalDateTime.now());
                    orderMapper.updateById(order);
                }
            }
            // 获取库检计划
            List<ApsWorkDetail> nextList = apsWorkDetailMapper.lambdaQuery()
                    .eq(ApsWorkDetail::getMaterNo, workDetailTask.getPlmid())
                    .eq(ApsWorkDetail::getPhaseCode, nextPhaseCode)
                    .in(ApsWorkDetail::getStatus, 2, 3)
                    .eq(ApsWorkDetail::getApsWorkOrderId, awd1.getApsWorkOrderId())
                    .list();
            for (ApsWorkDetail del : nextList) {
                del.setFinishCount(del.getFinishCount().add(new BigDecimal(partCount)));
                if (del.getTotalCount().compareTo(del.getFinishCount()) <= 0) {
                    del.setStatus(4);
                    del.setActualStartDateTime(del.getActualStartDateTime() != null ? del.getActualStartDateTime() : LocalDateTime.now());
                    del.setActualEndDateTime(LocalDateTime.now());
                } else {
                    del.setActualStartDateTime(LocalDateTime.now());
                    del.setStatus(3);
                }
                apsWorkDetailMapper.updateById(del);
            }
            int delId = 0;
            ApsWorkDetail nextAwd = null;
            if (!CollectionUtils.isEmpty(nextList)) {
                nextAwd = nextList.get(0);
                delId = nextList.get(0).getId();
            } else {
                nextAwd = new ApsWorkDetail();
                nextAwd.setPhaseCode(nextPhaseCode);
                nextAwd.setPhaseName(nextPhaseCode);
                nextAwd.setId(-1);
                nextAwd.setPhaseSeq(awd1.getPhaseSeq() + 1);
            }


            partUtilService.makePartKjReport(apsOrder.getConstructNo(), WorkshopProp.KJ_GROUP, WorkshopProp.KJ_GROUP, awd1.getMaterNo(), palletNumber, partCount + failCount, failCount, staffCode, delId);

            return nextAwd;


        }


    }

    public BasePageResVo<WorkshopAssembleListResVo> list(WorkshopAssembleListReqVo reqVo) {
        Page<ApsWorkDetail> apsWorkDetails = apsWorkDetailMapper.lambdaQuery()
                .in(ApsWorkDetail::getPhaseCode, WorkshopProp.PD_PHASE_CODE)
                .in(ApsWorkDetail::getStatus, 2, 3)
                .in(ApsWorkDetail::getGroupId, reqVo.getGroupId())
                .orderByAsc(ApsWorkDetail::getPlanStartDateTime)
                .page(reqVo.toPage());
        return BasePageResVo.of(apsWorkDetails, WorkshopAssembleListResVo.class);
    }

    @Transactional
    public void assembleStart(WorkshopAssembleStartReqVo reqVo) {
        ApsWorkDetail apsWorkDetail = null;
        if (reqVo.getId() != null && reqVo.getId() > 0) {
            apsWorkDetail = apsWorkDetailMapper.selectById(reqVo.getId());
        } else {
            Station station = stationMapper.lambdaQuery().eq(Station::getMyCode, reqVo.getStationCode()).one();
            Group group = null;
            if (ObjectUtils.isEmpty(station)) {
                group = groupMapper.selectOne(new QueryWrapper<Group>().eq("my_code", reqVo.getStationCode()));
            } else {
                group = groupMapper.selectGroupByStation(station.getId());
            }
            if (reqVo.getId() != null) {
                apsWorkDetail = apsWorkDetailMapper.selectById(reqVo.getId());
            } else {
                QueryWrapper<ApsWorkDetail> wrapper = Wrappers.query();
                wrapper.eq("wd.mater_no", reqVo.getAssemblyNumber());
                if(!ObjectUtils.isEmpty(group)){
                    wrapper.eq("wd.group_code", group.getMyCode());
                }
                wrapper.eq("wd.status", 2);
                wrapper.eq("wd.deleted", 0);
                if(StringUtils.hasText(reqVo.getConstructNo())){
                    wrapper.eq("tbo.construct_no", reqVo.getConstructNo());
                }
                wrapper.orderByAsc("wd.plan_start_date_time");
                wrapper.last("limit 1");
                apsWorkDetail = apsWorkDetailMapper.selectByOrder(wrapper);
            }

        }

        if (apsWorkDetail == null) {
            throw SyExceptionUtils.e("已开工或未查询到待开工的任务：{}", reqVo.getAssemblyNumber());
        }

        ApsWorkOrder apsWorkOrder = apsWorkOrderMapper.selectById(apsWorkDetail.getApsWorkOrderId());
        if (apsWorkOrder.getActualStartDateTime() == null) {
            apsWorkOrder.setActualStartDateTime(LocalDateTime.now());
            apsWorkOrderMapper.updateById(apsWorkOrder);
        }


        if (apsWorkDetail.getStatus() != 2 && apsWorkDetail.getStatus() != 3) {
            throw SyExceptionUtils.e("数据状态不正确");
        }

        if (!(apsWorkDetail.getPhaseCode().equalsIgnoreCase(WorkshopProp.PD_PHASE_CODE) || apsWorkDetail.getPhaseCode().equalsIgnoreCase(WorkshopProp.FM_PHASE_CODE) || apsWorkDetail.getPhaseCode().equalsIgnoreCase(WorkshopProp.PZ_PHASE_CODE) || apsWorkDetail.getPhaseCode().equalsIgnoreCase(WorkshopProp.XH_PHASE_CODE))) {
            throw SyExceptionUtils.e("该工序不是拼点或者拼装!");
        }

        boolean update = apsWorkDetailMapper.lambdaUpdate().set(ApsWorkDetail::getStatus, 3)
                .set(ApsWorkDetail::getActualStartDateTime, LocalDateTime.now())
                .eq(ApsWorkDetail::getId, apsWorkDetail.getId())
                .lt(ApsWorkDetail::getStatus, 3).update();


/*        if (apsWorkDetail.getStatus() == 2) {
            apsWorkDetail.setStatus(3);
            apsWorkDetail.setActualStartDateTime(LocalDateTime.now());
            apsWorkDetailMapper.updateById(apsWorkDetail);
        }*/
        /*Order one = orderMapper.lambdaQuery().eq(Order::getId, apsWorkDetail.getOrderId()).one();
        qmsOldApiClient.assemblyWorkStart(one.getConstructNo(), reqVo.getStationCode(), apsWorkDetail.getPlmId(), apsWorkDetail.getPhaseCode(), reqVo.getStaffCode(), apsWorkDetail.getUniqueCode());*/

//        Group group = groupMapper.selectById(apsWorkDetail.getGroupId());


    }

    @Transactional
    public void assemblePdEnd(WorkshopAssembleEndReqVo reqVo) {

        if (reqVo.getQuantity() == null || reqVo.getQuantity() < 1) {
            throw SyExceptionUtils.e("报工数量不能小于1");
        }

        ApsWorkDetail apsWorkDetail = apsWorkDetailMapper.selectById(reqVo.getId());
        if (apsWorkDetail.getStatus() > 3) {
            throw SyExceptionUtils.e("数据状态不正确");
        }
        boolean pzflage = false;
        if (WorkshopProp.PZ_PHASE_CODE.equalsIgnoreCase(apsWorkDetail.getPhaseCode()) || WorkshopProp.XH_PHASE_CODE.equalsIgnoreCase(apsWorkDetail.getPhaseCode())) {
            if (!apsWorkDetail.getMaterNo().contains("P1") && !apsWorkDetail.getMaterNo().contains("P2")
                    && !apsWorkDetail.getMaterNo().contains("P3") && !apsWorkDetail.getMaterNo().contains("P4") &&
                    !apsWorkDetail.getMaterNo().contains("P5") && !apsWorkDetail.getMaterNo().contains("P6")) {
                if (apsWorkDetail.getMaterName().contains("侧护板") || apsWorkDetail.getMaterName().contains("挡板组件") || apsWorkDetail.getMaterName().contains("拼垫板")) {
                    pzflage = true;
                } else {
                    pzflage = false;
                }

            } else {
                pzflage = true;
            }

        }
        if (pzflage) {
            Assert.isTrue(reqVo.getQuantity() == 1, "该工序只支持单件进行报工");
            //  兼容页面拼装进行报工
            WorkshopAssemblePzEndReqVo req = new WorkshopAssemblePzEndReqVo();
            Group group = groupMapper.selectGroupByWorkPlace(Wrappers.<Group>query()
                    .eq("ts.my_code", reqVo.getStationCode()));
            req.setWorkPlaceName(group.getMyCode());
            req.setAssemblyNumber(apsWorkDetail.getMaterNo());
            req.setWorker(reqVo.getStaffCode());
            req.setId(reqVo.getId());
            this.assemblePzEnd(req);
            return;
        } else {
            ApsWorkOrder apsWorkOrder = apsWorkOrderMapper.selectById(apsWorkDetail.getApsWorkOrderId());
            ApsOrder apsOrder = apsOrderMapper.selectById(apsWorkDetail.getApsOrderId());
            Order order = orderMapper.selectById(apsWorkDetail.getOrderId());

            // 获取该计划的所有数量
            int leftCount = apsWorkDetail.getTotalCount().subtract(apsWorkDetail.getFinishCount().add(new BigDecimal(reqVo.getQuantity()))).intValue();
            if (leftCount < 0) {
                throw SyExceptionUtils.e("{}报工数量超出{}件", apsWorkDetail.getMaterNo(), Math.abs(leftCount));
            }
            Group group = groupMapper.selectById(apsWorkDetail.getGroupId());
            // 拼装报工，生成拼装任务
            WorkDetailTask nextTask = new WorkDetailTask();
            nextTask.setMaterCode(apsWorkDetail.getMaterNo());
            nextTask.setMaterName(apsWorkDetail.getMaterName());
            nextTask.setApsWorkDetailId(apsWorkDetail.getId());
            nextTask.setTotalCount(reqVo.getQuantity());
            nextTask.setFinishCount(reqVo.getQuantity());
            nextTask.setFailCount(0);
            nextTask.setType(2);
            nextTask.setStationCode(reqVo.getStationCode());
            nextTask.setPlanStartDateTime(apsWorkDetail.getPlanStartDateTime());
            nextTask.setPlanEndDateTime(apsWorkDetail.getPlanEndDateTime());
            nextTask.setOrderCode(apsOrder.getOrderCode());
            nextTask.setGroupCode(group.getMyCode());
            nextTask.setPlmid(apsWorkDetail.getMaterNo());
            nextTask.setPhaseCode(apsWorkDetail.getPhaseCode());
            nextTask.setPhaseName(apsWorkDetail.getPhaseName());
            nextTask.setActualEndDateTime(LocalDateTime.now());
            nextTask.setStatus(3);
            workDetailTaskMapper.insert(nextTask);
            reqVo.setStaffCode(StringUtils.hasText(reqVo.getStaffCode()) ? reqVo.getStaffCode() : SySecurityUtils.getUserCode());
            WorkRecord workRecord = partUtilService.complatePartReport(apsOrder.getConstructNo(), group.getMyCode(), reqVo.getStationCode(), 2, 2,
                    apsWorkDetail.getMaterNo(), apsWorkDetail.getPhaseCode(), null,
                    reqVo.getQuantity(), 0, reqVo.getStaffCode(), nextTask.getId(), apsWorkDetail.getId(), null, null, null);


            // 获取子零件
            List<ApsWorkOrder> children = apsWorkOrderMapper.lambdaQuery().eq(ApsWorkOrder::getBomPid, apsWorkOrder.getBomId()).eq(ApsWorkOrder::getApsOrderId, apsWorkOrder.getApsOrderId()).list();
            List<String> plmIds = children.stream().map(ApsWorkOrder::getPlmId).distinct().collect(Collectors.toList());

            String constructNo = order.getConstructNo();
            List<String> conList = new ArrayList<>();
            PoolItem one = poolItemMapper.lambdaQuery().eq(PoolItem::getConstructCode, constructNo).eq(PoolItem::getStatus, 1).one();
            if(one != null){
                List<PoolItem> list = poolItemMapper.lambdaQuery().eq(PoolItem::getPoolId, one.getPoolId()).eq(PoolItem::getStatus, 1).list();
                conList =  list.stream().map(PoolItem::getConstructCode).distinct().collect(Collectors.toList());
            } else {
                conList.add(constructNo);
            }

            Map<String, List<Part>> plmIdPartMap = partMapper.lambdaQuery()
                    .in(Part::getPlmId, plmIds)
                    .in(Part::getConstructNo, conList)
                    .eq(Part::getPhaseCode, WorkshopProp.KJ_PHASE_CODE)
                    .list()
                    .stream()
                    .collect(Collectors.groupingBy(Part::getPlmId));
            log.info("[{}]套的需求数量：", reqVo.getQuantity());

            // 获取所有料位的零件和所有托盘的数量并分组
            for (ApsWorkOrder child : children) {
//                if (StringUtils.equals(WorkshopProp.WL_PHASE_CODE, child.getWorkChain())) {
//                    continue;
//                }
                BigDecimal multiply = child.getPartCount().multiply(new BigDecimal(reqVo.getQuantity()));
                List<Part> part = plmIdPartMap.get(child.getPlmId());
                if (ObjectUtils.isEmpty(part)) {
                    throw SyExceptionUtils.e("{}待加工的零件{}不存在", order.getConstructNo(), child.getPlmId());
                }

                // part集合的PartCount字段累加
                int totalPartCount = part.stream().map(Part::getPartCount).reduce(0, Integer::sum).intValue();

                log.info("名称：{}, plmId：{}，要扣减的数量：{}，已有数量:{}", child.getMaterName(), child.getPlmId(), multiply, totalPartCount);
                int reportCount = multiply.intValue();
                if (reportCount > totalPartCount) {
                    throw SyExceptionUtils.e("零件{}数量不足，现有数量{}，报工数量{}", child.getPlmId(), totalPartCount, reportCount);
                }

                partUtilService.kaiConsumerPart(part, order.getConstructNo(), reportCount, workRecord.getGroupNumber(), workRecord.getWorkStaffCode(), workRecord.getId(), apsWorkDetail.getMaterNo());

            }

            apsWorkDetailMapper.lambdaUpdate().eq(ApsWorkDetail::getId, apsWorkDetail.getId())
                    .set(ApsWorkDetail::getActualEndDateTime, LocalDateTime.now())
                    .set(ObjectUtils.isEmpty(apsWorkDetail.getActualStartDateTime()),ApsWorkDetail::getActualStartDateTime, LocalDateTime.now())
                    .set(apsWorkDetail.getTotalCount().compareTo(apsWorkDetail.getFinishCount().add(new BigDecimal(reqVo.getQuantity()))) <= 0,ApsWorkDetail::getStatus, 4)
                    .setSql("finish_count=finish_count+"+reqVo.getQuantity()).update();
//            String workChain = apsWorkOrder.getWorkChain();
//            String[] split = workChain.split("-");
//            int index = apsWorkDetail.getPhaseSeq();
            String nextPhaseCode = null;
            String nextPhasename = null;
            String nextWorkGroup = null;
            Optional<ApsWorkDetail> min = partUtilService.getNextWorkDetail(apsWorkDetail);
            if (min.isPresent()) {
                nextPhaseCode = min.get().getPhaseCode();
                if(WorkshopProp.KJ_PHASE_CODE.equalsIgnoreCase(min.get().getPhaseCode())){
                    apsWorkDetailMapper.lambdaUpdate().eq(ApsWorkDetail::getId, min.get().getId())
                            .set(ApsWorkDetail::getActualEndDateTime, LocalDateTime.now())
                            .set(ObjectUtils.isEmpty(apsWorkDetail.getActualStartDateTime()),ApsWorkDetail::getActualStartDateTime, LocalDateTime.now())
                            .set(apsWorkDetail.getFinishCount().add(new BigDecimal(reqVo.getQuantity())).compareTo(apsWorkDetail.getTotalCount())>=0,ApsWorkDetail::getStatus, 4)
                            .setSql("finish_count=finish_count+"+reqVo.getQuantity()).update();
                    //最后一道工序
                    partUtilService.updateOrderState(apsWorkOrder,apsOrder,reqVo.getQuantity());
                    nextPhaseCode = WorkshopProp.KJ_PHASE_CODE;
                    partUtilService.makePartKjReport(apsOrder.getConstructNo(),WorkshopProp.KJ_GROUP,WorkshopProp.KJ_GROUP,
                            apsWorkDetail.getMaterNo(),"PD",1,0, reqVo.getStaffCode(), min.get().getId()   );

                }else{
                    ApsWorkDetail awd = null;
                    if (WorkshopProp.PZ_PHASE_CODE.equalsIgnoreCase(apsWorkDetail.getPhaseCode())) {
                        awd = apsWorkDetailMapper.lambdaQuery()
                                .eq(ApsWorkDetail::getMaterNo, apsWorkOrder.getPlmId())
                                .eq(ApsWorkDetail::getPhaseCode, min.get().getPhaseCode())
                                .eq(ApsWorkDetail::getPhaseSeq, min.get().getPhaseSeq())
                                .eq(ApsWorkDetail::getApsWorkOrderId, apsWorkDetail.getApsWorkOrderId())
                                .isNull(ApsWorkDetail::getUniqueCode)
                                .orderByAsc(ApsWorkDetail::getApsOrderId)
                                .orderByAsc(ApsWorkDetail::getPlanStartDateTime)
                                .last("limit 1")
                                .one();
                        // 评点工序  但是工序是拼装，唯一号标记为评点
                        awd.setUniqueCode(WorkshopProp.PD_PHASE_CODE);
                        apsWorkDetailMapper.lambdaUpdate().eq(ApsWorkDetail::getId, awd.getId())
                                .set(ApsWorkDetail::getUniqueCode, WorkshopProp.PD_PHASE_CODE)
                                .update();

                    } else {

                        awd = apsWorkDetailMapper.lambdaQuery()
                                .eq(ApsWorkDetail::getMaterNo, apsWorkOrder.getPlmId())
                                .eq(ApsWorkDetail::getPhaseCode, min.get().getPhaseCode())
                                .eq(ApsWorkDetail::getPhaseSeq, min.get().getPhaseSeq())
                                .lt(ApsWorkDetail::getStatus, 4)
                                .eq(ApsWorkDetail::getApsWorkOrderId, apsWorkDetail.getApsWorkOrderId())
                                .orderByAsc(ApsWorkDetail::getApsOrderId)
                                .orderByAsc(ApsWorkDetail::getPlanStartDateTime)
                                .last("limit 1")
                                .one();
                    }

                    nextPhasename = awd.getPhaseName();
                    nextWorkGroup = awd.getGroupCode();
                    nextTask.setNextPhaseCode(awd.getPhaseCode());
                    nextTask.setNextGroupCode(nextWorkGroup);
                    workDetailTaskMapper.updateById(nextTask);
                    //解决当前计划大于1  下个计划总量是1 只生成单个任务的问题
                    if(reqVo.getQuantity()==1){
                        partUtilService.makeWorkDetailTask(awd, new BigDecimal(reqVo.getQuantity()), nextTask, apsWorkDetail.getPhaseCode());
                    }else{
                        if(awd.getTotalCount().intValue()==1){
                            int i=reqVo.getQuantity();
                            while (i>0&&awd!=null){
                                partUtilService.makeWorkDetailTask(awd, new BigDecimal(1), nextTask, apsWorkDetail.getPhaseCode());
                                awd = apsWorkDetailMapper.lambdaQuery()
                                        .eq(ApsWorkDetail::getMaterNo, apsWorkOrder.getPlmId())
                                        .eq(ApsWorkDetail::getPhaseCode, min.get().getPhaseCode())
                                        .eq(ApsWorkDetail::getPhaseSeq, min.get().getPhaseSeq())
                                        .lt(ApsWorkDetail::getStatus, 4)
                                        .eq(ApsWorkDetail::getApsWorkOrderId, apsWorkDetail.getApsWorkOrderId())
                                        .orderByAsc(ApsWorkDetail::getApsOrderId)
                                        .orderByAsc(ApsWorkDetail::getPlanStartDateTime)
                                        .last("limit 1")
                                        .one();
                                i--;
                            }

                        }else{
                            partUtilService.makeWorkDetailTask(awd, new BigDecimal(reqVo.getQuantity()), nextTask, apsWorkDetail.getPhaseCode());
                        }

                    }



                }

            } else {
                //最后一道工序
                partUtilService.updateOrderState(apsWorkOrder,apsOrder,reqVo.getQuantity());
                nextPhaseCode = WorkshopProp.KJ_PHASE_CODE;
                partUtilService.makePartKjReport(apsOrder.getConstructNo(),WorkshopProp.KJ_GROUP,WorkshopProp.KJ_GROUP,
                        apsWorkDetail.getMaterNo(),"PD",reqVo.getQuantity(),0, reqVo.getStaffCode(), apsWorkDetail.getId()   );
            }
            // 添加零件信息
            Part nextPart = partUtilService.createPart(apsOrder.getConstructNo(), apsWorkDetail.getMaterNo(), apsWorkDetail.getPhaseSeq(), apsWorkDetail.getPhaseCode(),
                    nextPhaseCode, nextPhasename, apsWorkOrder.getWorkChain(), nextWorkGroup, reqVo.getQuantity(), 0);
            partUtilService.putPallet(reqVo.getQuantity(), reqVo.getPalletNumber(), nextPart);
            partUtilService.createPartLog(1, nextPart, reqVo.getQuantity(), 0, reqVo.getPalletNumber(), workRecord, null);

            if (!StringUtils.hasText(apsWorkDetail.getUniqueCode())) {
                BigDecimal quantity = BigDecimal.valueOf(reqVo.getQuantity());
                // 通知QMS_SY生成质检任务
                apsInformQmsService.partStartWork(apsWorkDetail.getPlmId(), apsWorkOrder.getErpCode(), apsWorkOrder.getMaterName(), quantity, order.getConstructNo(), apsWorkDetail.getPhaseCode(), reqVo.getStationCode(), reqVo.getStaffCode(), reqVo.getPalletNumber(), reqVo.getStorageNumber(), apsWorkOrder.getWorkOrderCode(), PkgUtils.gen(apsOrder.getSeq()));
            } else {
                BigDecimal quantity = BigDecimal.valueOf(reqVo.getQuantity());
                // 通知QMS_SY生成质检任务
                apsInformQmsService.assembleStartWork(apsWorkDetail.getPlmId(), apsWorkOrder.getErpCode(), apsWorkOrder.getMaterName(), quantity, order.getConstructNo(), apsWorkDetail.getPhaseCode(), reqVo.getStationCode(), reqVo.getStaffCode(), apsWorkDetail.getUniqueCode(), PkgUtils.gen(apsOrder.getSeq()));
            }

//            qmsOldApiClient.assemblyWorkEnd(apsOrder.getConstructNo(), reqVo.getStationCode(), apsWorkDetail.getMaterNo(), apsWorkDetail.getPhaseCode(), reqVo.getStaffCode(), null);

        }
    }


    @Transactional
    public void partIn(WorkshopPartInReqVo reqVo) {
        // 原始数据落地
        if (reqVo.getQuantity() == null || reqVo.getQuantity() < 1) {
            throw SyExceptionUtils.e("数量不能小于1");
        }
        Part wlPart = partUtilService.createWlPart(reqVo);
        partUtilService.putWlPallet(reqVo);

    }

    @Transactional
    public void plateIn(WorkshopPlateInReqVo reqVo) {
        Part platePart = partService.getPart(1, reqVo.getPlateCode());
        if (reqVo.getStationCode().contains("SC_RGFJ_") || reqVo.getStationCode().contains("_SC_ZDFJ_")) {
            if (!"FJ".equals(platePart.getPhaseCode())) {
                throw SyExceptionUtils.e("钢板{}当前工序是{}，禁止到达分拣线", reqVo.getPlateCode(), platePart.getPhaseCode());
            }
        }


        plateUtils.plateIn(platePart, reqVo.getGroupCode(), reqVo.getStationCode(), reqVo.getPositionCode());
        plateUtils.createPartLog(platePart, reqVo.getGroupCode(), reqVo.getStationCode(), 5, reqVo.getPositionCode(), reqVo.getStationCode());
        // 如果当前有任务，则把任务的工位设置成当前工位
        WorkDetailTask one = workDetailTaskMapper.lambdaQuery()
                .lt(WorkDetailTask::getStatus, 3)
                .eq(WorkDetailTask::getMaterCode, reqVo.getPlateCode())
                .one();
        if (one != null) {
            one.setStationCode(reqVo.getStationCode());
            workDetailTaskMapper.updateById(one);
        }

        // 发送给普达系统
        if (projectConfig.isPudaOpen()) {
            SinoCamReceiveNestPlate nestPlate = sinoCamReceiveNestPlateMapper.lambdaQuery().eq(SinoCamReceiveNestPlate::getStockListNo, reqVo.getPlateCode()).one();
            SinoCamReceiveNestNest nestNest = sinoCamReceiveNestNestMapper.lambdaQuery().eq(SinoCamReceiveNestNest::getReceiveNestId, nestPlate.getReceiveNestId()).one();
            pudaApiClient.sendPlateEnd(reqVo.getStationCode(), reqVo.getPositionCode(), reqVo.getPlateCode(), nestNest.getNestId());
        }

        // 分拣先线到达即开工 reqVo.getStationCode().contains("_SC_RGFJ_")||
        if (reqVo.getStationCode().contains("_SC_ZDFJ_")) {
            WorkshopPlateStartWorkReqVo start = new WorkshopPlateStartWorkReqVo();
            start.setPhaseCode(WorkshopProp.FJ_PHASE_CODE);
            start.setStationCode(reqVo.getStationCode());
            start.setPlateCode(reqVo.getPlateCode());
            start.setStaffCode(WorkshopProp.DEFAULT_USER);
            try {
                plateStartWorkNew(start);
            } catch (Exception e) {
                log.info("分拣先线到达即开工失败", e);
                //throw new RuntimeException(e);
            }
        }
    }


    @Transactional
    public void plateOut(WorkshopPlateOutReqVo reqVo) {
        Part platePart = partService.getPart(1, reqVo.getPlateCode());
        plateUtils.plateOut(platePart, reqVo.getGroupCode(), reqVo.getStationCode());
        plateUtils.createPartLog(platePart, reqVo.getGroupCode(), reqVo.getStationCode(), 6, reqVo.getStationCode(), SySecurityUtils.getUserCode());
    }

    @Transactional
    public void platePdaFjEndWork(WorkshopPlateFjEndWorkReqVo reqVo) {
        // 找到钢板
        Plate plate = plateMapper.lambdaQuery().eq(Plate::getMaterCode, reqVo.getPlateCode()).one();
        if (plate.getStatus() != 5) {
            throw SyExceptionUtils.e("{}不是已出库的钢板无法开工", reqVo.getPlateCode());
        }
        // 更新出库信息
        WmsPlatePick wmsPlatePick = wmsPlatePickMapper.lambdaQuery().eq(WmsPlatePick::getPlateId, plate.getId()).eq(WmsPlatePick::getPlateState, 5).one();
        if (wmsPlatePick != null && wmsPlatePick.getPlateState() == 5) {
            wmsPlatePick.setPlateState(6);
            wmsPlatePickMapper.updateById(wmsPlatePick);
        }
        // 钢板任务
        WorkDetailTask task = workDetailTaskMapper.lambdaQuery()
                .eq(WorkDetailTask::getMaterCode, reqVo.getPlateCode())
                .eq(WorkDetailTask::getPhaseCode, WorkshopProp.FJ_PHASE_CODE)
                .lt(WorkDetailTask::getStatus, 3)
                .one();

//        String constructNo=null;
        // 找到套料信息的所有零件
        List<SinoCamReceiveNestPart> nestPartList = sinoCamReceiveNestPartMapper.lambdaQuery()
                .eq(SinoCamReceiveNestPart::getPlateCode, plate.getMaterCode())
                .eq(SinoCamReceiveNestPart::getPartId, reqVo.getPartCode().trim())
                .orderByAsc(SinoCamReceiveNestPart::getNestPlanId)
//                .apply("receive_nest_id in (select receive_nest_id from tb_third_sinocam_receive_nest_plate where stock_list_no={0})", plate.getMaterCode())
                .list();
//        nestPartList.sort(Comparator.comparing(SinoCamReceiveNestPart::getNestPlanId));
        int leftSortCount = reqVo.getFinishCount() + reqVo.getFailCount();//需要待分拣的数量
        int currentReport = 0;//本次报工数量
        int leftFailReport = reqVo.getFailCount();//剩余报工失败的数量
        for (SinoCamReceiveNestPart nestPart : nestPartList) {
            if (leftSortCount < 1) {
                break;
            }
            if (!nestPart.getPartId().equals(reqVo.getPartCode())) {
                continue;
            }
            if (nestPart.getQuantity() <= nestPart.getSortingCount()) {
                continue;
            }
            if (nestPart.getQuantity() < nestPart.getSortingCount() + leftSortCount) {
                //套料信息不够分拣
                currentReport = nestPart.getQuantity() - nestPart.getSortingCount();
                leftSortCount = leftSortCount - currentReport;
                nestPart.setSortingCount(nestPart.getSortingCount() + currentReport);
            } else {
                nestPart.setSortingCount(nestPart.getSortingCount() + leftSortCount);
                currentReport = leftSortCount;
                leftSortCount = 0;
            }
            sinoCamReceiveNestPartMapper.updateById(nestPart);
                // 获取切割计划
            ApsWorkDetail workQgDetail = apsWorkDetailMapper.selectById(Integer.parseInt(nestPart.getNestPlanId()));
                // 获取分拣计划
            ApsWorkDetail fjDetail = apsWorkDetailMapper.lambdaQuery()
                        .eq(ApsWorkDetail::getMaterNo, nestPart.getPartId())
                        .eq(ApsWorkDetail::getApsWorkOrderId, workQgDetail.getApsWorkOrderId())
                        .eq(ApsWorkDetail::getPhaseCode, WorkshopProp.FJ_PHASE_CODE)
                        .last(" LIMIT 1 ").one();

                // 获取工序最小序号
                QueryWrapper<ApsWorkDetail> query = Wrappers.query();
                query.eq("aps_work_order_id", workQgDetail.getApsWorkOrderId());
                query.eq("mater_no", nestPart.getPartId());
                query.gt("phase_seq", fjDetail.getPhaseSeq());
                query.orderByAsc("phase_seq");
                query.last(" LIMIT 1 ");
                String nextPhase = apsWorkDetailMapper.nextPhase(query);
                // 对分捡工序进行维护
                ApsWorkOrder apsWorkOrder = apsWorkOrderMapper.selectById(fjDetail.getApsWorkOrderId());
                if(currentReport>=leftFailReport){
                    this.complateAwd(apsWorkOrder, fjDetail, nextPhase, currentReport, currentReport, leftFailReport, nestPart, reqVo.getPalletCode(), reqVo.getStaffCode(), reqVo.getStationCode(), reqVo.getPlateCode());
                    leftFailReport=0;
                }else if(leftFailReport>0){
                    this.complateAwd(apsWorkOrder, fjDetail, nextPhase, currentReport, currentReport, currentReport, nestPart, reqVo.getPalletCode(), reqVo.getStaffCode(), reqVo.getStationCode(), reqVo.getPlateCode());
                    leftFailReport=leftFailReport-currentReport;
                }

        }
        if (leftSortCount > 0) {
            throw SyExceptionUtils.e("{}分拣报工的零件数量超过套料的零件数量{}或已经报工完成", reqVo.getPartCode(), leftSortCount);
        }
        nestPartList = sinoCamReceiveNestPartMapper.lambdaQuery()
                .eq(SinoCamReceiveNestPart::getPlateCode, plate.getMaterCode())
                .list();
        List<SinoCamReceiveNestPart> collect = nestPartList.stream().filter(e -> e.getQuantity() > e.getSortingCount()).collect(Collectors.toList());
        ApsWorkDetail plateDetail = apsWorkDetailMapper.lambdaQuery().eq(ApsWorkDetail::getMaterNo, reqVo.getPlateCode()).eq(ApsWorkDetail::getPhaseCode, reqVo.getPhaseCode()).one();
        plateDetail.setActualEndDateTime(LocalDateTime.now());

        if (collect.isEmpty()) {
            plateDetail.setStatus(4);
            plateDetail.setProcessCount(new BigDecimal(1));
            plateDetail.setPartCount(new BigDecimal(1));
            //钢板分拣任务完成
            task.setStatus(3);
            task.setFinishCount(1);
            task.setFailCount(0);
            task.setTotalCount(1);
//                task.setEndStaffCode(reqVo.getStaffCode());
            task.setActualEndDateTime(LocalDateTime.now());
            workDetailTaskMapper.updateById(task);

            // 添加钢板分拣报工记录
            List<WorkRecord> recordList = workRecordMapper.lambdaQuery().eq(WorkRecord::getOperationId, task.getId()).eq(WorkRecord::getWorkType, 1)
                    .eq(WorkRecord::getPlmid, reqVo.getPalletCode()).eq(WorkRecord::getType, 1).orderByDesc(WorkRecord::getId).list();
            Integer startId = null;
            LocalDateTime startTime = null;
            if (!CollectionUtils.isEmpty(recordList)) {
                startId = recordList.get(0).getId();
                startTime = recordList.get(0).getWorkTime();
            }
            reqVo.setStaffCode(StringUtils.hasText(reqVo.getStaffCode()) ? reqVo.getStaffCode() : SySecurityUtils.getUserCode());
            partUtilService.complatePartReport(task.getOrderCode(), task.getGroupCode(), task.getStationCode(), 1, 2, plate.getNestId()
                    , task.getPhaseCode(), reqVo.getPlateCode(), 1, 0, reqVo.getStaffCode(),
                    task.getId(), plateDetail.getId(), startId, startTime, null);
            plateUtils.clearPlate(reqVo.getPlateCode());

            plate.setStatus(6);
            plateMapper.updateById(plate);


        }
        plateDetail.setActualEndDateTime(LocalDateTime.now());
        apsWorkDetailMapper.updateById(plateDetail);

    }

    /**
     * 完成计划的数量
     *
     * @param awd
     * @param nextPhase     最小工序序号
     * @param complateCount 报工数量  (包含异常件数量)
     * @return
     */
    private void complateAwd(ApsWorkOrder apsWorkOrder, ApsWorkDetail awd, String nextPhase, int leftCount1, int complateCount, int leftFailReport,
                                             SinoCamReceiveNestPart nestPart, String palletCode, String staffCode, String stationCode, String plateCode) {
        ApsOrder apsOrder = apsOrderMapper.selectById(awd.getApsOrderId());
        //  创建分拣任务
        WorkDetailTask nextTask = new WorkDetailTask();
        nextTask.setMaterCode(nestPart.getPartId());
        nextTask.setMaterName(nestPart.getPartName());
        nextTask.setPlanStartDateTime(awd.getPlanStartDateTime());
        nextTask.setPlanEndDateTime(awd.getPlanEndDateTime());
        nextTask.setPartPath(nestPart.getPartMapUrl());
        nextTask.setOrderCode(apsOrder.getConstructNo());
        nextTask.setWeight(nestPart.getNetWeight());
        nextTask.setStationCode(stationCode);
        nextTask.setTotalCount(complateCount);
        nextTask.setFinishCount(complateCount);
        nextTask.setApsWorkDetailId(awd.getId());
        nextTask.setType(2);
        SinoCamReceiveNestPlate nestPlate = sinoCamReceiveNestPlateMapper.lambdaQuery().eq(SinoCamReceiveNestPlate::getStockListNo, nestPart.getPlateCode()).one();
        nextTask.setNestPlateId(nestPlate != null ? nestPlate.getId() : null);
        nextTask.setFailCount(leftFailReport);
        nextTask.setGroupCode(awd.getGroupCode());
        nextTask.setPlmid(nestPart.getPartId());
        nextTask.setLength(nestPart.getLength());
        nextTask.setThickness(nestPart.getThickness());
        nextTask.setTexture(apsWorkOrder.getTexture());
        nextTask.setWidth(nestPart.getWidth());
        nextTask.setPlateCode(nestPart.getPlateCode());
        nextTask.setNestId(nestPart.getNestId());
        nextTask.setPhaseCode(WorkshopProp.FJ_PHASE_CODE);
        nextTask.setPhaseName(WorkshopProp.FJ_PHASE_CODE);
        nextTask.setActualStartDateTime(LocalDateTime.now().minusMinutes(2));
        nextTask.setActualEndDateTime(LocalDateTime.now());
        nextTask.setStatus(3);
        workDetailTaskMapper.insert(nextTask);
        apsWorkDetailMapper.lambdaUpdate().eq(ApsWorkDetail::getId, awd.getId())
                .set(ApsWorkDetail::getUniqueCode, nestPart.getPlateCode())
                .set(ObjectUtils.isEmpty(awd.getActualStartDateTime()),ApsWorkDetail::getActualStartDateTime, LocalDateTime.now())
                .set(ApsWorkDetail::getActualEndDateTime, LocalDateTime.now())
                .setSql("finish_count=finish_count+"+complateCount).update();

        //  添加零件分拣报工记录
        staffCode = StringUtils.hasText(staffCode) ? staffCode : SySecurityUtils.getUserCode();
        WorkRecord workRecord = partUtilService.complatePartReport(apsOrder.getConstructNo(), awd.getGroupCode(), stationCode, 2, 2, nestPart.getPartId(),
                WorkshopProp.FJ_PHASE_CODE, palletCode, complateCount, leftFailReport, staffCode, nextTask.getId(), awd.getId(), null, null, plateCode);
        partUtilService.updateDetailState(awd.getId());



        Part oldpart = partService.getPart(apsOrder.getConstructNo(), nestPart.getPartId(), WorkshopProp.FJ_PHASE_CODE);

        if (oldpart == null) {
            throw SyExceptionUtils.e("缺少在制品，没有零件:{}工序{}", nestPart.getPartId(), WorkshopProp.FJ_PHASE_CODE);
        }
        partUtilService.consumePart(oldpart, complateCount, awd.getGroupCode(), staffCode, workRecord.getId(), plateCode);
        if (StringUtils.hasText(nextPhase) && !nextPhase.equals(WorkshopProp.KJ_PHASE_CODE)) {
            ApsWorkDetail nextDetail = apsWorkDetailMapper.lambdaQuery()
                    .eq(ApsWorkDetail::getMaterNo, nestPart.getPartId())
                    .eq(ApsWorkDetail::getApsWorkOrderId, awd.getApsWorkOrderId())
                    .eq(ApsWorkDetail::getPhaseCode, nextPhase).last("LIMIT 1") .one();
            if (ObjectUtils.isEmpty(nextDetail)) {
                throw SyExceptionUtils.e("未找到下一个可完工的计划:{}，单号：{}", nestPart.getPartId(), awd.getApsWorkOrderId());
            }
            boolean flage=true;//是否创建下个任务
            int taskMakeCount=complateCount;//待创建的任务数量
            List<WorkDetailTask> list = workDetailTaskMapper.lambdaQuery().eq(WorkDetailTask::getApsWorkDetailId, nextDetail.getId()).list();
            int taskFishCount = list.stream().mapToInt(WorkDetailTask::getTotalCount).sum();// 已创建的任务数量
            if (nextDetail.getTotalCount().intValue()<=taskFishCount) {
                flage=false;
            }else if(nextDetail.getTotalCount().intValue()<=(taskFishCount+complateCount)){
                taskMakeCount=nextDetail.getTotalCount().intValue()-taskFishCount;
                if(taskMakeCount<=0){
                    flage=false;
                }
            }
            nextTask.setNextPhaseCode(nextDetail.getPhaseCode());
            nextTask.setNextGroupCode(nextDetail.getGroupCode());
            workDetailTaskMapper.updateById(nextTask);
            //报工的数量小于计划的数量
            if (complateCount > leftFailReport) {
                if(flage){
                    partUtilService.makeWorkDetailTask(nextTask, nextDetail, taskMakeCount, WorkshopProp.FJ_PHASE_CODE, nestPart);
                }
                Part newPart = partUtilService.createPart(apsOrder.getConstructNo(), awd.getMaterNo(), awd.getPhaseSeq(), awd.getPhaseCode(), nextDetail.getPhaseCode(), nextDetail.getPhaseName(), apsWorkOrder.getWorkChain(), nextDetail.getGroupCode(), complateCount - leftFailReport, leftFailReport);
                partUtilService.createPartLog(1, newPart, complateCount - leftFailReport, leftFailReport, palletCode, workRecord, null);
                partUtilService.putPallet(complateCount - leftFailReport, palletCode, newPart);
                partExceptService.createPartExcept(apsOrder.getConstructNo(), newPart.getPlmId(), newPart.getPrePhaseCode(), newPart.getPhaseCode(), newPart.getPhaseSeq(), leftFailReport, staffCode, awd.getId(),
                        awd.getGroupCode(), stationCode, plateCode);
            } else {
                if(flage) {
                    partUtilService.makeWorkDetailTask(nextTask,nextDetail, taskMakeCount, WorkshopProp.FJ_PHASE_CODE, nestPart);
                }
                Part newPart = partUtilService.createPart(apsOrder.getConstructNo(), awd.getMaterNo(), awd.getPhaseSeq(), awd.getPhaseCode(), nextDetail.getPhaseCode(), nextDetail.getPhaseName(), apsWorkOrder.getWorkChain(), nextDetail.getGroupCode(), 0, complateCount);
                partUtilService.createPartLog(1, newPart, 0, complateCount, palletCode, workRecord, null);
                partExceptService.createPartExcept(apsOrder.getConstructNo(), awd.getMaterNo(), WorkshopProp.FJ_PHASE_CODE, nextDetail.getPhaseCode(), null, complateCount, staffCode, awd.getId(), awd.getGroupCode(), stationCode, plateCode);
            }
        } else {
            //  如果是最后一道工序  或者是库检
            if (complateCount > leftFailReport) {
                // 添加下道工序的零件
                Part nextPart = partUtilService.createPart(apsOrder.getConstructNo(), apsWorkOrder.getPlmId(), awd.getPhaseSeq(), awd.getPhaseCode(), WorkshopProp.KJ_PHASE_CODE, WorkshopProp.KJ_PHASE_CODE, apsWorkOrder.getWorkChain(), null, complateCount - leftFailReport, leftFailReport);
                partUtilService.createPartLog(1, nextPart, complateCount - leftFailReport, leftFailReport, palletCode, workRecord, null);
                //零件装盘
                partUtilService.putPallet(complateCount - leftFailReport, palletCode, nextPart);
                partExceptService.createPartExcept(apsOrder.getConstructNo(), nextPart.getPlmId(), nextPart.getPrePhaseCode(), nextPart.getPhaseCode(), nextPart.getPhaseSeq(), leftFailReport, staffCode, awd.getId(), awd.getGroupCode(), stationCode, plateCode);

                partUtilService.updateOrderState(apsWorkOrder,  apsOrder ,complateCount - leftFailReport);


            } else {
                Part nextPart = partUtilService.createPart(apsOrder.getConstructNo(), apsWorkOrder.getPlmId(), awd.getPhaseSeq(), awd.getPhaseCode(), WorkshopProp.KJ_PHASE_CODE, WorkshopProp.KJ_PHASE_CODE, apsWorkOrder.getWorkChain(), null, 0, complateCount);
                partUtilService.createPartLog(1, nextPart, 0 ,complateCount, palletCode, workRecord, null);
                partExceptService.createPartExcept(apsOrder.getConstructNo(), awd.getMaterNo(), WorkshopProp.FJ_PHASE_CODE, WorkshopProp.KJ_PHASE_CODE, null, complateCount, staffCode, awd.getId(), awd.getGroupCode(), stationCode, plateCode);
            }
            int delId = 0;
            ApsWorkDetail nextDetail  = apsWorkDetailMapper.lambdaQuery()
                    .eq(ApsWorkDetail::getMaterNo, nestPart.getPartId())
                    .eq(ApsWorkDetail::getApsWorkOrderId, awd.getApsWorkOrderId())
                    .eq(ApsWorkDetail::getPhaseCode, WorkshopProp.KJ_PHASE_CODE)
                    .last("LIMIT 1") .one();
            if (!ObjectUtils.isEmpty(nextDetail)) {
                delId=nextDetail.getId();
                apsWorkDetailMapper.lambdaUpdate().eq(ApsWorkDetail::getId, nextDetail.getId())
                        .set(ApsWorkDetail::getUniqueCode, nestPart.getPlateCode())
                        .set(ObjectUtils.isEmpty(nextDetail.getActualStartDateTime()),ApsWorkDetail::getActualStartDateTime, LocalDateTime.now())
                        .set(ApsWorkDetail::getActualEndDateTime, LocalDateTime.now())
                        .set(nextDetail.getFinishCount().add(new BigDecimal(complateCount - leftFailReport)).compareTo(nextDetail.getTotalCount())>=0,ApsWorkDetail::getStatus, 4)
                        .setSql("finish_count=finish_count+"+(complateCount - leftFailReport)).update();
                partUtilService.updateDetailState(nextDetail.getId());

            }
            partUtilService.makePartKjReport(apsOrder.getConstructNo(), WorkshopProp.KJ_GROUP, WorkshopProp.KJ_GROUP, awd.getMaterNo(), palletCode, complateCount, leftFailReport, staffCode, delId);
        }



    }

    public void startWorkByPart(EmbeddedStartModel reqVo) {
        String placeName = reqVo.getWorkPlaceName();
        String worker = reqVo.getWorker();
        Group group = groupMapper.selectOne(new QueryWrapper<Group>().eq("my_code", placeName));
        if (ObjectUtils.isEmpty(group)) {
            group = groupMapper.selectGroupByWorkPlace(Wrappers.<Group>query()
                    .eq("ts.my_code", placeName));
        }
        if(ObjectUtils.isEmpty(group)){
          throw SyExceptionUtils.e("{}找不到对应的工作组！", placeName);
        }

        String groupNumer = group.getMyCode();
        if(org.apache.commons.lang3.StringUtils.isBlank(reqVo.getUniqueCode())){
            //  零件只要有开工中的计划，则不在进行开工
            ApsWorkDetail detail = apsWorkDetailMapper.lambdaQuery().eq(ApsWorkDetail::getStatus, 3).eq(ApsWorkDetail::getMaterNo, reqVo.getAssemblyNumber())
                    .eq(ApsWorkDetail::getGroupCode, groupNumer).last("limit 1").one();
            if(!ObjectUtils.isEmpty(detail)){
              return;
            }
        }
        WorkDetailTask task = workDetailTaskMapper.lambdaQuery()
                .eq(WorkDetailTask::getGroupCode, groupNumer)
                .eq(WorkDetailTask::getPlmid, reqVo.getAssemblyNumber())
                .eq(WorkDetailTask::getStatus, 1).last("limit 1").one();
        if(!ObjectUtils.isEmpty(task)){
            ApsWorkDetail workDetail = apsWorkDetailMapper.selectById(task.getApsWorkDetailId());
            ApsWorkOrder apsWorkOrder = apsWorkOrderMapper.selectById(workDetail.getApsWorkOrderId());
            if (apsWorkOrder.getActualStartDateTime() == null) {
                apsWorkOrder.setActualStartDateTime(LocalDateTime.now());
                apsWorkOrderMapper.updateById(apsWorkOrder);
            }
            partUtilService.startPartReport(groupNumer, placeName, 2, 1, task.getPlmid(), task.getPhaseCode(),
                    reqVo.getUniqueCode(), null, worker, task.getId(), task.getApsWorkDetailId());
            task.setActualStartDateTime(LocalDateTime.now());
            task.setStatus(2);
            task.setModifyUsername(reqVo.getWorker());
            workDetailTaskMapper.updateById(task);
            LambdaUpdateWrapper<ApsWorkDetail> query = new LambdaUpdateWrapper<>();
            query.eq(ApsWorkDetail::getId, task.getApsWorkDetailId());
            query.eq(StringUtils.hasText(reqVo.getUniqueCode()), ApsWorkDetail::getUniqueCode, reqVo.getUniqueCode());
            query.set(ApsWorkDetail::getStatus, 3);
            query.set(ApsWorkDetail::getActualStartDateTime, new Date());
            apsWorkDetailMapper.update(null, query);
        }





    }

    public BasePageResVo<PlatePartListResVo> platePartList(WorkshopPlatePartListReqVo reqVo) {

        Group group = groupMapper.selectById(reqVo.getId());

        QueryWrapper<SinoCamReceiveNestPart> query = Wrappers.query();
        if (group != null) {
            query.eq("task.group_code", group.getMyCode());
        } else {
            query.eq(StringUtils.hasText(reqVo.getGroupCode()), "task.group_code", reqVo.getGroupCode());
        }
        if (StringUtils.hasText(reqVo.getMaterName())) {
            query.like(" awd.mater_name", reqVo.getMaterName());
        }
        if (StringUtils.hasText(reqVo.getPlateCode())) {
            query.like(" part.plate_code", reqVo.getPlateCode());
        }
        if (StringUtils.hasText(reqVo.getPkgCode())) {
            query.eq("ao.seq", PkgUtils.rollBack(reqVo.getPkgCode()));
        }
        if (StringUtils.hasText(reqVo.getConstructNo())) {
            query.like("ao.construct_no", reqVo.getConstructNo());
        }
        if (StringUtils.hasText(reqVo.getMaterCode())) {
            query.like("awd.mater_no", reqVo.getMaterCode());
        }

        query.isNotNull("awd.id");
        query.apply("part.quantity > part.sorting_count");
        query.orderByAsc("part.plate_code");
        query.orderByAsc("ao.seq");
        Page<PlatePartListResVo> list = sinoCamReceiveNestPartMapper.platePartList(reqVo.toPage(), query);
        for (PlatePartListResVo e : list.getRecords()) {
            e.setDimension(String.format("%s * %s * %s", e.getLength() == null ? "-" : e.getLength(), e.getWidth() == null ? "-" : e.getWidth(), e.getThickness() == null ? "-" : e.getThickness()));
//            e.setDrawing(WorkshopProp.NESTING_DRAWING_CTX + e.getDrawing());
//            e.setDrawing(e.getDrawing());
//            e.setPlatePdfUrl(WorkshopProp.NESTING_DRAWING_CTX + e.getPlatePdfUrl());
            e.setPlatePdfUrl(e.getPlatePdfUrl());
            e.setPhaseCode(WorkshopProp.FJ_PHASE_CODE);

            if (StringUtils.hasText(e.getDrawing())) {
                e.setDrawing(String.format(projectConfig.getUrlPre(), e.getMaterCode() + ".png", e.getDrawing()));
            }

        }

        BasePageResVo<PlatePartListResVo> resVo = new BasePageResVo<>(list.getTotal(), list.getRecords());

        for (PlatePartListResVo datum : resVo.getData()) {
            if (datum.getSplitNum() != null) {
                datum.setPkgCode(PkgUtils.gen(datum.getSplitNum()));
            }

            // 开始分捡后的下一道工序
            QueryWrapper<ApsWorkDetail> query1 = Wrappers.query();
            query1.eq("aps_work_order_id", datum.getApsWorkOrderId());
            query1.gt("phase_seq", datum.getPhaseSeq());
            Integer minPhaseSeq = apsWorkDetailMapper.minPhaseSeq(query1);
            if (minPhaseSeq != null) {
                ApsWorkDetail nextList = apsWorkDetailMapper.lambdaQuery()
                        .eq(ApsWorkDetail::getApsWorkOrderId, datum.getApsWorkOrderId())
                        .gt(ApsWorkDetail::getPhaseSeq, minPhaseSeq)
                        .orderByAsc(ApsWorkDetail::getPhaseSeq)
                        .last(" limit 1")
                        .one();

                if (nextList != null) {
                    datum.setNextGroupCode(nextList.getGroupCode());
                    datum.setNextPhaseCode(nextList.getPhaseCode());
                }
            }
            datum.setPlateName("钢板");
        }
        return resVo;
    }

    @Transactional
    public void assemblePzEnd(WorkshopAssemblePzEndReqVo reqVo) {
        ApsWorkDetail apsWorkDetail = null;
        if ("4-3_FM_00".equals(reqVo.getWorkPlaceName())) {
            // 本工位 是进行的赋码的报工
            apsWorkDetail = apsWorkDetailMapper.lambdaQuery()
                    .eq(ApsWorkDetail::getMaterNo, reqVo.getAssemblyNumber())
                    .eq(ApsWorkDetail::getGroupCode, reqVo.getWorkPlaceName())
                    .eq(ApsWorkDetail::getPhaseCode, WorkshopProp.FM_PHASE_CODE)
                    .eq(ApsWorkDetail::getStatus, 3)
                    .isNull(ApsWorkDetail::getUniqueCode)  //只处理未绑定过唯一好的任务
                    .orderByAsc(ApsWorkDetail::getApsOrderId)
                    .last("limit 1")
                    .one();

        } else {
            QueryWrapper<ApsWorkDetail> wrapper = Wrappers.query();
            wrapper.eq("wd.mater_no", reqVo.getAssemblyNumber());
            wrapper.eq("wd.group_code", reqVo.getWorkPlaceName());
            if (!"4-2_RGHJ_00".equals(reqVo.getWorkPlaceName())) {
                // 4-2_RGHJ_00本工位  拼装用的是XH工序
                wrapper.eq("wd.phase_code", WorkshopProp.PZ_PHASE_CODE);
            }
            wrapper.lt("wd.status", 4);
            wrapper.isNull("wd.unique_code");
            wrapper.eq("wd.deleted", 0);
            if (StringUtils.hasText(reqVo.getConstructNo())) {
                wrapper.eq("tbo.construct_no", reqVo.getConstructNo());
            } else if (StringUtils.hasText(reqVo.getUniqueCode()) && reqVo.getUniqueCode().contains("-")) {
                //  一拼件  次逻辑零时处理，后期会去掉
                String str = reqVo.getUniqueCode();
                String[] parts = str.split("-");  // 按 "-" 分割字符串
                wrapper.like("tbo.construct_no", parts[1]);
            }
            if (reqVo.getId() != null) {
                wrapper.eq("wd.id ", reqVo.getId());
            }

            wrapper.orderByAsc("wd.plan_start_date_time");
            wrapper.last("limit 1");
            apsWorkDetail = apsWorkDetailMapper.selectByOrder(wrapper);

        }

        if (apsWorkDetail == null) {
            throw SyExceptionUtils.e("{}没有找到已开工的任务", reqVo.getAssemblyNumber());
        }

        apsWorkDetailMapper.lambdaUpdate()
                .eq(ApsWorkDetail::getId, apsWorkDetail.getId())
                .set(ApsWorkDetail::getActualEndDateTime, LocalDateTime.now())
                .set(ObjectUtils.isEmpty(apsWorkDetail.getActualStartDateTime()), ApsWorkDetail::getActualStartDateTime, LocalDateTime.now())
                .set(ApsWorkDetail::getUniqueCode, reqVo.getUniqueCode())
                .set(apsWorkDetail.getTotalCount().compareTo(apsWorkDetail.getFinishCount().add(new BigDecimal(1))) > 0, ApsWorkDetail::getStatus, 3)
                .set(apsWorkDetail.getTotalCount().compareTo(apsWorkDetail.getFinishCount().add(new BigDecimal(1))) <= 0, ApsWorkDetail::getStatus, 4)
                .setSql("finish_count=finish_count+" + 1)
                .update();

        ApsOrder apsOrder = apsOrderMapper.selectById(apsWorkDetail.getApsOrderId());
        // 拼装报工，生成拼装任务
        Group group = groupMapper.selectById(apsWorkDetail.getGroupId());
        WorkDetailTask oldTask = new WorkDetailTask();
        oldTask.setMaterCode(apsWorkDetail.getMaterNo());
        oldTask.setMaterName(apsWorkDetail.getMaterName());
        oldTask.setApsWorkDetailId(apsWorkDetail.getId());
        oldTask.setTotalCount(1);
        oldTask.setFinishCount(1);
        oldTask.setFailCount(0);
        oldTask.setType(2);
        oldTask.setPlanStartDateTime(apsWorkDetail.getPlanStartDateTime());
        oldTask.setPlanEndDateTime(apsWorkDetail.getPlanEndDateTime());
        oldTask.setGroupCode(group.getMyCode());
        oldTask.setPlmid(apsWorkDetail.getMaterNo());
        oldTask.setPhaseCode(apsWorkDetail.getPhaseCode());
        oldTask.setPhaseName(apsWorkDetail.getPhaseName());
        oldTask.setActualStartDateTime(LocalDateTime.now());
        oldTask.setActualEndDateTime(LocalDateTime.now());
        oldTask.setStatus(3);
        workDetailTaskMapper.insert(oldTask);

        Order order = orderMapper.selectById(apsOrder.getOrderId());


        ApsWorkOrder apsWorkOrder = apsWorkOrderMapper.selectById(apsWorkDetail.getApsWorkOrderId());
        // 获取子零件
        List<ApsWorkOrder> children = apsWorkOrderMapper.lambdaQuery().eq(ApsWorkOrder::getBomPid, apsWorkOrder.getBomId()).eq(ApsWorkOrder::getApsOrderId, apsWorkOrder.getApsOrderId()).list();
        List<PoolItem> poolItemList = poolItemMapper.selectByConstructCode(apsOrder.getConstructNo());
        List<String> poolConstructCodeList = poolItemList.stream().map(PoolItem::getConstructCode).distinct().collect(Collectors.toList());

        List<String> plmIds = children.stream().map(ApsWorkOrder::getPlmId).distinct().collect(Collectors.toList());
        Map<String, List<Part>> plmIdPartMap = null;
        if (!CollectionUtils.isEmpty(plmIds)) {
            if (CollUtil.isEmpty(poolConstructCodeList)) {
                poolConstructCodeList.add(order.getConstructNo());
            }
            plmIdPartMap = partMapper.lambdaQuery()
                    .in(Part::getPlmId, plmIds)
                    .in(Part::getConstructNo, poolConstructCodeList)
                    .eq(Part::getPhaseCode, WorkshopProp.KJ_PHASE_CODE)
                    .list()
                    .stream()
                    .collect(Collectors.groupingBy(Part::getPlmId));
        } else {
            plmIdPartMap = new HashMap<>();
        }

        boolean yipinFlag = isYipin(apsWorkOrder);
        // 扣减唯一号的件
        PartPallet one = null;
        if (!yipinFlag && StringUtils.isEmpty(reqVo.getUniqueCode())) {
            one = partPalletMapper.lambdaQuery()
                    .in(PartPallet::getPlmId, plmIds)
                    .isNotNull(PartPallet::getUniqueCode)
                    .eq(StringUtils.hasText(reqVo.getConstructNo()), PartPallet::getConstructNo, reqVo.getConstructNo())
                    .eq(PartPallet::getPhaseCode, WorkshopProp.KJ_PHASE_CODE)
                    .last("limit 1")
                    .one();
        } else if ("4-3_FM_00".equals(reqVo.getWorkPlaceName())) {
            // 赋码  进行特殊处理
            plmIds = new LinkedList<>();
            plmIds.add(reqVo.getAssemblyNumber());
            one = new PartPallet();
            one.setPlmId(reqVo.getAssemblyNumber());
            one.setUniqueCode(reqVo.getUniqueCode());
        } else if (yipinFlag && StringUtils.isEmpty(reqVo.getUniqueCode())) {
            String s = this.maxCode(apsWorkDetail.getMaterNo(), apsOrder.getConstructNo());
            if (StringUtils.isEmpty(s)) {
                s = "001";
            } else {
                s = String.format("%03d", Integer.parseInt(s.substring(s.length() - 3)) + 1);
            }
            reqVo.setUniqueCode(this.getAssembleType(apsWorkDetail) + apsOrder.getConstructNo() + "-" + s);
        } else {
            try {
                one = partPalletMapper.lambdaQuery().eq(PartPallet::getUniqueCode, reqVo.getUniqueCode()).one();
            } catch (Exception e) {
                throw SyExceptionUtils.e("唯一号{}重复", reqVo.getUniqueCode());
            }
        }
        if (!ObjectUtils.isEmpty(one)) {
            PartPallet finalOne = one;
            plmIds.removeIf(e -> e.equals(finalOne.getPlmId()));
            if (StringUtils.isEmpty(reqVo.getUniqueCode())) {
                reqVo.setUniqueCode(one.getUniqueCode());
            }
        }

        if (yipinFlag && StringUtils.isEmpty(reqVo.getUniqueCode())) {
            String s = this.maxCode(apsWorkDetail.getMaterNo(), apsOrder.getConstructNo());
            if (StringUtils.isEmpty(s)) {
                s = "001";
            } else {
                s = String.format("%03d", Integer.parseInt(s.substring(s.length() - 3)) + 1);
            }
            reqVo.setUniqueCode(this.getAssembleType(apsWorkDetail) + apsOrder.getConstructNo() + "-" + s);
        }

        if (!yipinFlag && one == null) {
            throw SyExceptionUtils.e("唯一件未找到");
        }

        if (StringUtils.isEmpty(apsWorkDetail.getUniqueCode())) {
            ApsWorkDetail check = apsWorkDetailMapper.selectById(apsWorkDetail.getId());
            if (StringUtils.isEmpty(check.getUniqueCode())) {
                apsWorkDetailMapper.lambdaUpdate()
                        .set(ApsWorkDetail::getUniqueCode, reqVo.getUniqueCode())
                        .eq(ApsWorkDetail::getId, apsWorkDetail.getId())
                        .update();
//                apsWorkDetail.setUniqueCode(reqVo.getUniqueCode());
//                apsWorkDetailMapper.updateById(apsWorkDetail);
            } else if (!check.getUniqueCode().equalsIgnoreCase(reqVo.getUniqueCode())) {
                throw SyExceptionUtils.e("数据读取异常，请再次提交");
            }
        }
        //一拼件检测唯一号
        if (yipinFlag && !StringUtils.isEmpty(reqVo.getUniqueCode())) {
            List<ApsWorkDetail> list = apsWorkDetailMapper.lambdaQuery().eq(ApsWorkDetail::getUniqueCode, reqVo.getUniqueCode()).list();
            for (ApsWorkDetail check : list) {
                if (!check.getId().equals(apsWorkDetail.getId())) {
                    throw SyExceptionUtils.e("唯一号重复");
                }
            }
        }

        reqVo.setWorker(StringUtils.hasText(reqVo.getWorker()) ? reqVo.getWorker() : SySecurityUtils.getUserCode());
        WorkRecord workRecord = partUtilService.complatePartReport(apsOrder.getConstructNo(), group.getMyCode(), reqVo.getWorkPlaceName(), 2, 2,
                apsWorkDetail.getMaterNo(), apsWorkDetail.getPhaseCode(), reqVo.getUniqueCode(), 1, 0,
                reqVo.getWorker(), oldTask.getId(), apsWorkDetail.getId(), null, null, null);
        for (ApsWorkOrder child : children) {
            BigDecimal multiply = child.getPartCount().multiply(new BigDecimal(1));
            // 如果是唯一件
            if (!yipinFlag && one.getPlmId().equals(child.getPlmId())) {
                log.info("进行拼装报工消费掉子组件{}", one.getPlmId());
                partPalletMapper.deleteReal(one.getId());
            }

            // 如果是零件的外购件
            List<Part> part = plmIdPartMap.get(child.getPlmId());
            if (ObjectUtils.isEmpty(part)) {
                throw SyExceptionUtils.e("{}子零件未生产结束", child.getPlmId());
            }

            Integer reduce = part.stream().map(Part::getPartCount).reduce(0, Integer::sum);
            if (multiply.intValue() > reduce) {
                throw SyExceptionUtils.e("{}工位上零件{}数量不足，现有数量{}，报工数量{}", reqVo.getWorkPlaceName(), child.getPlmId(), one.getPartCount(), multiply.intValue());
            }

            partUtilService.kaiConsumerPart(part, order.getConstructNo(), multiply.intValue(), workRecord.getGroupNumber(), workRecord.getWorkStaffCode(), workRecord.getId(), apsWorkDetail.getMaterNo());

            /*
            Integer myConsCount = part.stream().filter(e->e.getConstructNo().equals(apsOrder.getConstructNo())).map(Part::getPartCount).reduce(0, Integer::sum);
            if (multiply.intValue() > myConsCount) {
                // 需要借件
                // 先排序，相同号的排最前面，否则为最后面
                // 从最前面开始扣，如果施工号不同，则为借件
                List<Part> collect = part.stream()
                        .sorted((e1, e2) -> {
                            if (e1.getConstructNo().equals(e2.getConstructNo())) {
                                return 1;
                            }
                            return -1;
                        })
                        .collect(Collectors.toList());


                int shengyu = multiply.intValue();


                for (Part part1 : collect) {
                    if (part1.getPartCount() == 0) {
                        continue;
                    }

                    int consumeCount = part1.getPartCount();
                    if (part1.getPartCount() > shengyu) {
                        consumeCount = shengyu;
//                        partUtilService.consumePart(part1, shengyu, workRecord.getGroupNumber(), workRecord.getWorkStaffCode(), workRecord.getId(), apsWorkDetail.getMaterNo());
//                        shengyu = 0;
                    }
//                    partUtilService.kaiConsumerPart(part, reportCount, workRecord.getGroupNumber(), workRecord.getWorkStaffCode(), workRecord.getId(), apsWorkDetail.getMaterNo());


                    shengyu -= consumeCount;

                    if(apsOrder.getConstructNo().equals(part1.getConstructNo())){
                        if (shengyu == 0) {
                            break;
                        } else {
                            continue;
                        }
                    }


                    PoolPart jiePoolPart = poolPartMapper.lambdaQuery()
                            .eq(PoolPart::getMyCode, apsOrder.getConstructNo())
                            .eq(PoolPart::getTargetCode, part1.getConstructNo())
                            .eq(PoolPart::getPlmId, part1.getPlmId())
                            .eq(PoolPart::getPhaseCode, part1.getPhaseCode())
                            .one();
                    if (jiePoolPart == null) {
                        jiePoolPart = new PoolPart();
                        jiePoolPart.setMyCode(apsOrder.getConstructNo());
                        jiePoolPart.setTargetCode(part1.getConstructNo());
                        jiePoolPart.setPlmId(part1.getPlmId());
                        jiePoolPart.setInTotal(consumeCount);
                        jiePoolPart.setPhaseCode(part1.getPhaseCode());
                        jiePoolPart.setOutTotal(0);
                        jiePoolPart.setVersion(1);
                        poolPartMapper.insert(jiePoolPart);


                    } else {
                        jiePoolPart.setInTotal(jiePoolPart.getInTotal() + consumeCount);
                        int i = poolPartMapper.updateById(jiePoolPart);
                        if(i <= 0){
                            throw SyExceptionUtils.e("请重新报工!");
                        }
                    }

                    if (shengyu == 0) {
                        break;
                    }

                }


            } else {
                // 不需要借件
                Optional<Part> first = part.stream().filter(e -> e.getConstructNo().equals(apsOrder.getConstructNo())).findFirst();
                partUtilService.consumePart(first.get(), multiply.intValue(), workRecord.getGroupNumber(), workRecord.getWorkStaffCode(), workRecord.getId(), apsWorkDetail.getMaterNo());

            }
             */

        }


        String nextPhaseCode = null;
        String nextPhasename = null;
        String nextWorkGroup = null;
        Optional<ApsWorkDetail> nextWorkDetail = partUtilService.getNextWorkDetail(apsWorkDetail);
        if (nextWorkDetail.isPresent()) {
            nextPhaseCode = nextWorkDetail.get().getPhaseCode();
            if (WorkshopProp.KJ_PHASE_CODE.equalsIgnoreCase(nextPhaseCode)) {
                ApsWorkDetail nextDetail = nextWorkDetail.get();
                //最后一道工序
                apsWorkDetailMapper.lambdaUpdate().eq(ApsWorkDetail::getId, nextDetail.getId())
                        .set(ApsWorkDetail::getUniqueCode, reqVo.getUniqueCode())
                        .set(ApsWorkDetail::getActualEndDateTime, LocalDateTime.now())
                        .set(ObjectUtils.isEmpty(apsWorkDetail.getActualStartDateTime()), ApsWorkDetail::getActualStartDateTime, LocalDateTime.now())
                        .set(apsWorkDetail.getFinishCount().add(new BigDecimal(1)).compareTo(apsWorkDetail.getTotalCount()) >= 0, ApsWorkDetail::getStatus, 4)
                        .setSql("finish_count=finish_count+1").update();
                partUtilService.updateOrderState(apsWorkOrder, apsOrder, 1);
                nextPhaseCode = WorkshopProp.KJ_PHASE_CODE;

                partUtilService.makePartKjReport(apsOrder.getConstructNo(), WorkshopProp.KJ_GROUP, WorkshopProp.KJ_GROUP,
                        nextDetail.getMaterNo(), reqVo.getUniqueCode(), 1, 0, reqVo.getWorker(), nextDetail.getId());
            } else {
                List<ApsWorkDetail> aleryDetail = apsWorkDetailMapper.lambdaQuery()
                        .eq(ApsWorkDetail::getUniqueCode, reqVo.getUniqueCode())
                        .eq(ApsWorkDetail::getMaterNo, apsWorkOrder.getPlmId())
                        .eq(ApsWorkDetail::getPhaseCode, nextWorkDetail.get().getPhaseCode())
                        .eq(ApsWorkDetail::getPhaseSeq, nextWorkDetail.get().getPhaseSeq())
                        .list();
                if (!CollectionUtils.isEmpty(aleryDetail)) {
                    throw SyExceptionUtils.e(String.format("工件%s唯一号%s重复！", apsWorkOrder.getPlmId(), reqVo.getUniqueCode()));
                }
                ApsWorkDetail awd = apsWorkDetailMapper.lambdaQuery()
                        .eq(ApsWorkDetail::getMaterNo, apsWorkOrder.getPlmId())
                        .eq(ApsWorkDetail::getPhaseCode, nextWorkDetail.get().getPhaseCode())
                        //.eq(ApsWorkDetail::getPhaseSeq, nextWorkDetail.get().getPhaseSeq())
                        .eq(ApsWorkDetail::getApsWorkOrderId, apsWorkDetail.getApsWorkOrderId())
                        .isNull(ApsWorkDetail::getUniqueCode)
                        .orderByDesc(ApsWorkDetail::getCreateDateTime)
                        .last("limit 1")
                        .one();

                awd.setUniqueCode(reqVo.getUniqueCode());
                apsWorkDetailMapper.lambdaUpdate().eq(ApsWorkDetail::getId, awd.getId())
                        .set(ApsWorkDetail::getUniqueCode, reqVo.getUniqueCode())
                        .update();

                nextPhasename = awd.getPhaseName();
                nextWorkGroup = awd.getGroupCode();
                oldTask.setNextGroupCode(awd.getGroupCode());
                oldTask.setNextPhaseCode(awd.getPhaseCode());
                workDetailTaskMapper.updateById(oldTask);

                int count = 1;
                List<WorkDetailTask> list = workDetailTaskMapper.lambdaQuery().eq(WorkDetailTask::getApsWorkDetailId, awd.getId()).list();
                if (CollectionUtils.isEmpty(list)) {
                    partUtilService.makeUniqueCodeWorkDetailTask(awd, apsWorkDetail.getPhaseCode(), awd.getId(), oldTask, reqVo.getUniqueCode());
                } else {
                    throw SyExceptionUtils.e(String.format("工件%s工序%s生成任务数量超限", awd.getMaterNo(), awd.getPhaseCode()));
                }

            }


        } else {
            //最后一道工序
            partUtilService.updateOrderState(apsWorkOrder, apsOrder, 1);
            nextPhaseCode = WorkshopProp.KJ_PHASE_CODE;
            partUtilService.makePartKjReport(apsOrder.getConstructNo(), WorkshopProp.KJ_GROUP, WorkshopProp.KJ_GROUP,
                    apsWorkDetail.getMaterNo(), reqVo.getUniqueCode(), 1, 0, reqVo.getWorker(), apsWorkDetail.getId());

        }
        Part partNew = partUtilService.createPart(apsOrder.getConstructNo(), apsWorkDetail.getMaterNo(), apsWorkDetail.getPhaseSeq(), apsWorkDetail.getPhaseCode(), nextPhaseCode, nextPhasename, apsWorkOrder.getWorkChain(), nextWorkGroup, 1, 0);
        partUtilService.createPartLog(1, partNew, 1, 0, null, workRecord, reqVo.getUniqueCode());
        partUtilService.putUniqueCode(partNew, reqVo.getWorkPlaceName(), reqVo.getUniqueCode());
        // 通知wms组件报工
        PartsReportingAddDto partReport = apsWorkDetailMapper.getAssePartInfo(apsWorkDetail.getId());
        if (!ObjectUtils.isEmpty(partReport)) {
            partReport.setWorkPlace(reqVo.getWorkPlaceName());
            partReport.setWorkers(reqVo.getWorker());
            if (nextWorkDetail.isPresent()) {
                partReport.setNextGroupNumber(nextWorkDetail.get().getGroupCode());
                partReport.setNextNxphase(nextWorkDetail.get().getPhaseCode());
                Optional<ApsWorkDetail> nextTowWorkDetail = partUtilService.getNextWorkDetail(nextWorkDetail.get());
                if (nextTowWorkDetail.isPresent()) {
                    partReport.setNextTwoGroupNumber(nextTowWorkDetail.get().getGroupCode());
                    partReport.setNextTwoNxphase(nextTowWorkDetail.get().getPhaseCode());
                }
            }
            wmsApiClient.AsseSyc(partReport);
        }

        // 通知QMS_SY生成质检任务
        apsInformQmsService.assembleStartWork(reqVo.getAssemblyNumber(), apsWorkOrder.getErpCode(), apsWorkOrder.getMaterName(), BigDecimal.ONE, apsOrder.getConstructNo(), apsWorkDetail.getPhaseCode(), reqVo.getWorkPlaceName(), reqVo.getWorker(), reqVo.getUniqueCode(), PkgUtils.gen(apsOrder.getSeq()));

//        qmsOldApiClient.assemblyWorkEnd(apsOrder.getConstructNo(), reqVo.getWorkPlaceName(), apsWorkDetail.getMaterNo(), apsWorkDetail.getPhaseCode(), reqVo.getWorker(), reqVo.getUniqueCode());

    }
//前梁左侧护板
    private String getAssembleType(ApsWorkDetail apsWorkDetail) {

        if (apsWorkDetail.getMaterName().equals("挡板组件") && apsWorkDetail.getMaterNo().contains("A_")) {
            return "DBA";
        }
        if (apsWorkDetail.getMaterName().contains("底座一拼") || apsWorkDetail.getMaterNo().contains("-0301P")) {
            return "D";
        }
        if (apsWorkDetail.getMaterName().contains("顶梁一拼") || apsWorkDetail.getMaterNo().contains("-0101P")) {
            return "L";
        }
        if (apsWorkDetail.getMaterName().contains("掩护梁一拼") || apsWorkDetail.getMaterNo().contains("-0201P")) {
            return "Y";
        }
        if (apsWorkDetail.getMaterName().contains("顶梁左侧护板")) {
            return "DZ";
        }
        if (apsWorkDetail.getMaterName().contains("顶梁右侧护板")) {
            return "DY";
        }
        if (apsWorkDetail.getMaterName().contains("掩护梁左侧护板")) {
            return "YZ";
        }
        if (apsWorkDetail.getMaterName().contains("掩护梁右侧护板")) {
            return "YY";
        }
        if (apsWorkDetail.getMaterName().contains("前梁左侧护板")) {
            return "QZ";
        }
        if (apsWorkDetail.getMaterName().contains("前梁右侧护板")) {
            return "QY";
        }

        if (apsWorkDetail.getMaterName().contains("挡板组件")) {
            return "DB";
        }

        return "";
    }

    /**
     * 判断是否为一拼件
     *
     * @param apsWorkOrder
     * @return
     */
    public boolean isYipin(ApsWorkOrder apsWorkOrder) {

        if (apsWorkOrder.getPlmId().replace("_170", "").endsWith("P1")) {
            return true;
        }
        if (apsWorkOrder.getMaterName().contains("侧护板") || apsWorkOrder.getMaterName().contains("挡板组件")) {
            return true;
        }
      /*  List<ApsWorkOrder> awo = apsWorkOrderMapper.lambdaQuery()
                .eq(ApsWorkOrder::getApsOrderId, apsWorkOrder.getApsOrderId())
                .eq(ApsWorkOrder::getOrderId, apsWorkOrder.getOrderId())
                .gt(ApsWorkOrder::getLevel, apsWorkOrder.getLevel())
                .list();

        for (ApsWorkOrder workOrder : awo) {
            if (workOrder.getWorkChain().contains(WorkshopProp.PZ_PHASE_CODE)) {
                return false;
            }
        }
    */


        return false;
    }

    /**
     * 组件报工
     */
    @Transactional
    public void partEndWorkAssemble(WorkshopPartEndWorkReqVo reqVo) {
        String staffCode = stationService.getStaffCode(reqVo.getStaffCode(), reqVo.getStationCode());

        if (StringUtils.hasText(staffCode)) {
            reqVo.setStaffCode(staffCode);
        } else {
            staffCode = stationService.getStaffCode(reqVo.getStaffCode(), reqVo.getGroupCode());
            reqVo.setStaffCode(staffCode);
        }
        WorkDetailTask oldTask = workDetailTaskMapper.lambdaQuery()
                .eq(WorkDetailTask::getPlmid, reqVo.getPlmid())
                .eq(WorkDetailTask::getPhaseCode, reqVo.getPhaseCode())
                .eq(WorkDetailTask::getId, reqVo.getId())
                .one();
        if (ObjectUtils.isEmpty(oldTask)) {
            throw SyExceptionUtils.e(String.format("%s没有找到开工中的任务", reqVo.getPlmid()));
        }

        if (oldTask.getStatus() == 3) {
            throw SyExceptionUtils.e(String.format("%s任务已完工", reqVo.getPlmid()));
        }

        oldTask.setFinishCount(1);
        oldTask.setFailCount(0);
        oldTask.setStatus(3);
        oldTask.setModifyUsername(reqVo.getStaffCode());
        oldTask.setActualEndDateTime(LocalDateTime.now());
        workDetailTaskMapper.updateById(oldTask);
        apsWorkDetailMapper.lambdaUpdate().set(ApsWorkDetail::getStatus,4)
                .set(ApsWorkDetail::getFinishCount,1).set(ApsWorkDetail::getActualEndDateTime,LocalDateTime.now())
                .eq(ApsWorkDetail::getId,oldTask.getApsWorkDetailId()).update();
        ApsWorkDetail oldAwd = apsWorkDetailMapper.selectById(oldTask.getApsWorkDetailId());
        if(oldAwd.getActualStartDateTime()==null){
            apsWorkDetailMapper.lambdaUpdate().set(ApsWorkDetail::getActualStartDateTime,LocalDateTime.now())
                    .eq(ApsWorkDetail::getId,oldTask.getApsWorkDetailId()).update();
        }
        ApsWorkOrder oldAwo = apsWorkOrderMapper.selectById(oldAwd.getApsWorkOrderId());
        ApsOrder apsOrder = apsOrderMapper.selectById(oldAwd.getApsOrderId());
        List<WorkRecord> recordList = workRecordMapper.lambdaQuery().eq(WorkRecord::getOperationId, oldTask.getId()).eq(WorkRecord::getWorkType, 1)
                .eq(WorkRecord::getPlmid, reqVo.getPlmid()).eq(WorkRecord::getType, 2).orderByDesc(WorkRecord::getId).list();
        Integer startId = null;
        LocalDateTime startTime = null;
        if (!CollectionUtils.isEmpty(recordList)) {
            startId = recordList.get(0).getId();
            startTime = recordList.get(0).getWorkTime();
        }
        reqVo.setStaffCode(StringUtils.hasText(reqVo.getStaffCode()) ? reqVo.getStaffCode() : SySecurityUtils.getUserCode());
        WorkRecord workRecord = partUtilService.complatePartReport(apsOrder.getConstructNo(), oldTask.getGroupCode(), reqVo.getStationCode(), 2, 2, reqVo.getPlmid()
                , reqVo.getPhaseCode(), reqVo.getUniqueCode(), reqVo.getPartCount(), reqVo.getFailCount(), reqVo.getStaffCode(),
                oldTask.getId(), oldAwd.getId(), startId, startTime, null);

        // 直接扣除零件，不需要从托盘扣除
        Part oldpart = partService.getPart(apsOrder.getConstructNo(), reqVo.getPlmid(), reqVo.getPhaseCode());

        if (ObjectUtils.isEmpty(oldpart)) {
//            throw SyExceptionUtils.e(String.format("待加工的零件%s没找到待加工的工序%s", reqVo.getPlmid(), reqVo.getPhaseCode()));
            throw SyExceptionUtils.e(String.format("待加工的零件%s没找到工序%s的在制品", reqVo.getPlmid(), reqVo.getPhaseCode()));
        }
        partUtilService.consumePart(oldpart, reqVo.getPartCount(), workRecord.getGroupNumber(), workRecord.getWorkStaffCode(), workRecord.getId(), null);

        String nextPhaseCode = null;
        String nextGroupCode = null;
//        Integer apsWorkDetailId = null;
        //  index  前工序    index+1当前工序      index+2 下道工序
        Optional<ApsWorkDetail> nextWorkDetail = partUtilService.getNextWorkDetail(oldAwd);
//        List<ApsWorkDetail> allDetail = apsWorkDetailMapper.lambdaQuery().eq(ApsWorkDetail::getApsWorkOrderId, oldAwd.getApsWorkOrderId()).list();
//        Optional<ApsWorkDetail> min = allDetail.stream().filter(e -> e.getPhaseSeq() > oldAwd.getPhaseSeq()).min(Comparator.comparing(ApsWorkDetail::getPhaseSeq));
        if (nextWorkDetail.isPresent()) {
            List<ApsWorkDetail> aleryDetail = apsWorkDetailMapper.lambdaQuery().eq(ApsWorkDetail::getUniqueCode, reqVo.getUniqueCode()).eq(ApsWorkDetail::getMaterNo, reqVo.getPlmid())
                    .eq(ApsWorkDetail::getPhaseCode, nextWorkDetail.get().getPhaseCode()).list();
            if (!CollectionUtils.isEmpty(aleryDetail)) { //
                throw SyExceptionUtils.e(String.format("工件%s工序%s唯一号%s计划已完工！", reqVo.getPlmid(), nextWorkDetail.get().getPhaseCode(), reqVo.getUniqueCode()));
            }

            if (!redissonLockClient.checkRepeatSubmit(reqVo.getPlmid()+reqVo.getPhaseCode(), 5)) {
                // 如果是重复提交，在这里处理业务逻辑，例如抛出业务异常
                throw new SyException("请勿重复提交");
            }
            ApsWorkDetail awd = apsWorkDetailMapper.lambdaQuery()
                    .eq(ApsWorkDetail::getMaterNo, reqVo.getPlmid())
                    .eq(ApsWorkDetail::getPhaseCode, nextWorkDetail.get().getPhaseCode())
                    .eq(ApsWorkDetail::getApsWorkOrderId, oldAwd.getApsWorkOrderId())
                    .isNull(ApsWorkDetail::getUniqueCode)
                    .last("limit 1")
                    .one();
            if (ObjectUtils.isEmpty(awd)) { //
                throw SyExceptionUtils.e(String.format("工件%s工序%s未找到待加工的计划！", reqVo.getPlmid(), nextWorkDetail.get().getPhaseCode()));
            }
            awd.setUniqueCode(reqVo.getUniqueCode());
            boolean flage=apsWorkDetailMapper.lambdaUpdate().set(ApsWorkDetail::getUniqueCode, reqVo.getUniqueCode())
                    .eq(ApsWorkDetail::getId, awd.getId()).isNull(ApsWorkDetail::getUniqueCode)
                    .update();
            redissonLockClient.rmtLock(reqVo.getPlmid()+reqVo.getPhaseCode());
           if(!flage){
               throw new RuntimeException(String.format("请勿重复提交,请等等%s秒",2));
           }

            nextPhaseCode = awd.getPhaseCode();
            nextGroupCode = awd.getGroupCode();
            oldTask.setNextPhaseCode(nextPhaseCode);
            oldTask.setNextGroupCode(nextGroupCode);
            workDetailTaskMapper.updateById(oldTask);
            partUtilService.makeUniqueCodeWorkDetailTask(awd, oldAwd.getPhaseCode(), awd.getId(), oldTask,reqVo.getUniqueCode());

        } else {
            if (!redissonLockClient.checkRepeatSubmit(reqVo.getPlmid()+reqVo.getPhaseCode()+oldAwd.getId(), 10)) {
                // 如果是重复提交，在这里处理业务逻辑，例如抛出业务异常
                throw new SyException("请勿重复提交");
            }


            nextPhaseCode = WorkshopProp.KJ_PHASE_CODE;
            ApsWorkOrder apsWorkOrder = apsWorkOrderMapper.selectById(oldAwd.getApsWorkOrderId());
            Order order = orderMapper.selectById(apsOrder.getOrderId());
            if (order.getOrderType().equals(1)) {
                partUtilService.updateOrderState(apsWorkOrder,apsOrder,reqVo.getPartCount());
            } else if ( (order.getOrderType().equals(4) || order.getOrderType().equals(3))  &&  apsWorkOrder.getLevel().equals(2)) {

                if(!ObjectUtils.isEmpty(apsWorkOrder)&& StringUtils.hasText(apsWorkOrder.getWorkChain())&& apsWorkOrder.getWorkChain().contains("-")){
                    String str = apsWorkOrder.getWorkChain();
                    String[] parts = str.split("-");  // 按 "-" 分割字符串
                    String lastPart = parts[parts.length - 1];  // 获取最后一个部分
                    int sum = apsWorkDetailMapper.lambdaQuery().eq(ApsWorkDetail::getApsWorkOrderId, apsWorkOrder.getId())
                            .eq(ApsWorkDetail::getPhaseCode, lastPart).list().stream().mapToInt(t->t.getFinishCount().intValue()).sum();
                    apsWorkOrderMapper.lambdaUpdate().eq(ApsWorkOrder::getId, apsWorkOrder.getId())
                            .set(ApsWorkOrder::getActualEndDateTime, LocalDateTime.now())
                            .set(apsWorkOrder.getOrderCount().intValue() == sum,ApsWorkOrder::getStatus, 4)
                            .set(ApsWorkOrder::getFinishCount, sum)
                            .update();

                }else{
                    apsWorkOrderMapper.lambdaUpdate().eq(ApsWorkOrder::getId, oldAwd.getApsWorkOrderId())
                            .set(ApsWorkOrder::getActualEndDateTime, LocalDateTime.now())
                            .setSql("finish_count=finish_count+"+reqVo.getPartCount()).update();

                    if (apsWorkOrder.getFinishCount().intValue() == apsWorkOrder.getOrderCount().intValue()) {
                        apsWorkOrderMapper.lambdaUpdate().eq(ApsWorkOrder::getId, apsWorkOrder.getId())
                                .set(ApsWorkOrder::getStatus, 4).update();
                    }
                }





                if (apsWorkOrder.getPid()==null&&apsWorkOrder.getFinishCount().intValue() == apsWorkOrder.getOrderCount().intValue()) {
                    LambdaQueryChainWrapper<ApsWorkOrder> workOrderWrapper = apsWorkOrderMapper.lambdaQuery();
                    workOrderWrapper.eq(ApsWorkOrder::getApsOrderId, apsWorkOrder.getApsOrderId());
                    workOrderWrapper.gt(ApsWorkOrder::getLevel, 1);
                    workOrderWrapper.ne(ApsWorkOrder::getId, apsWorkOrder.getId());
                    workOrderWrapper.apply(" finish_count <> order_count");
                    List<ApsWorkOrder> list = workOrderWrapper.list();
                    if (!list.isEmpty()) {
                        return ;
                    }
                    apsOrder.setFinishQty(apsOrder.getOrderQty());
                    apsOrder.setActualFinishTime(LocalDateTime.now());
                    apsOrder.setOrderStatus(9);
                    apsOrderMapper.updateById(apsOrder);

                    LambdaQueryChainWrapper<ApsWorkOrder> workOrderWrapper1 = apsWorkOrderMapper.lambdaQuery();
                    workOrderWrapper1.eq(ApsWorkOrder::getApsOrderId, apsWorkOrder.getApsOrderId());
                    workOrderWrapper1.eq(ApsWorkOrder::getLevel, 1);
                    workOrderWrapper1.lt(ApsWorkOrder::getStatus,4);
                    List<ApsWorkOrder> list2 = workOrderWrapper1.list();

                    for (ApsWorkOrder workOrder : list2) {
                        workOrder.setFinishCount(workOrder.getOrderCount());
                        workOrder.setActualEndDateTime(LocalDateTime.now());
                        workOrder.setStatus(4);
                        apsWorkOrderMapper.updateById(workOrder);

                        List<ApsWorkDetail> list1 = apsWorkDetailMapper.lambdaQuery().eq(ApsWorkDetail::getApsWorkOrderId, workOrder.getId())
                                .lt(ApsWorkDetail::getStatus, 4).list();
                        for (ApsWorkDetail workDetail : list1) {
                            workDetail.setStatus(4);
                            workDetail.setActualStartDateTime(LocalDateTime.now());
                            workDetail.setActualEndDateTime(LocalDateTime.now());
//                                workDetail.setFinishCount(workDetail.getTotalCount());
                            apsWorkDetailMapper.updateById(workDetail);
                        }
                    }

                    List<ApsOrder> list1 = apsOrderMapper.lambdaQuery()
                            .eq(ApsOrder::getOrderId, apsOrder.getOrderId())
                            .ne(ApsOrder::getId, apsOrder.getId())
                            .apply(" order_qty <> finish_qty")
                            .list();

                    if(!list1.isEmpty()){
                        return ;
                    }

                    order.setFinishQty(order.getOrderQty());
                    order.setActualEndDateTime(LocalDateTime.now());
                    order.setOrderStatus(9);
                    orderMapper.updateById(order);
                }
            }
            redissonLockClient.rmtLock(reqVo.getPlmid()+reqVo.getPhaseCode()+oldAwd.getId());


        }

        Part nextPart = partUtilService.createPart(apsOrder.getConstructNo(), oldAwd.getMaterNo(), oldAwd.getPhaseSeq(), oldAwd.getPhaseCode(), nextPhaseCode, nextPhaseCode,
                oldpart.getWorkChain(), nextGroupCode, reqVo.getPartCount(), 0);
        partUtilService.createPartLog(4, nextPart, reqVo.getPartCount(), 0, null, workRecord, oldAwd.getUniqueCode());
        if (!WorkshopProp.PD_PHASE_CODE.equals(reqVo.getUniqueCode())) {
            partUtilService.putUniqueCode(nextPart, reqVo.getStationCode(), reqVo.getUniqueCode());
        }

        // 通知wms组件报工
        PartsReportingAddDto partReport = apsWorkDetailMapper.getAssePartInfo(oldAwd.getId());
        if (!ObjectUtils.isEmpty(partReport)) {
            partReport.setWorkPlace(reqVo.getStationCode());
            partReport.setWorkers(reqVo.getStaffCode());
            if (nextWorkDetail.isPresent()) {
                partReport.setNextGroupNumber(nextWorkDetail.get().getGroupCode());
                partReport.setNextNxphase(nextWorkDetail.get().getPhaseCode());
                Optional<ApsWorkDetail> nextTowWorkDetail = partUtilService.getNextWorkDetail(nextWorkDetail.get());
                if (nextTowWorkDetail.isPresent()) {
                    partReport.setNextTwoGroupNumber(nextTowWorkDetail.get().getGroupCode());
                    partReport.setNextTwoNxphase(nextTowWorkDetail.get().getPhaseCode());
                }
            }else{
                try {
                    OrderBom orderBom = orderBomMapper.lambdaQuery().eq(OrderBom::getPlmId, oldAwd.getMaterNo()).last(" limit 1 ").one();
                    if (orderBom != null) {
                        OrderBom orderBomP = orderBomMapper.lambdaQuery().eq(OrderBom::getId, orderBom.getPid()).last(" limit 1 ").one();
                        if (orderBomP != null) {
                            ApsWorkDetail apsWorkDetail = apsWorkDetailMapper.lambdaQuery().eq(ApsWorkDetail::getMaterNo, orderBomP.getPlmId()).orderByAsc(ApsWorkDetail::getPhaseSeq).last(" limit 1 ").one();
                            if (apsWorkDetail != null) {
                                partReport.setNextGroupNumber(apsWorkDetail.getGroupCode());
                                partReport.setNextNxphase(apsWorkDetail.getPhaseCode());
                            }
                        }
                    }
                } catch (Exception e) {
                    partReport.setNextGroupNumber(WorkshopProp.KJ_PHASE_CODE);
                    partReport.setNextNxphase(WorkshopProp.KJ_PHASE_CODE);
                }

            }
            wmsApiClient.AsseSyc(partReport);
        }
        if(StringUtils.hasText(reqVo.getStationCode())){
            try {
                stationMapper.returnToRequester(reqVo.getStationCode(), 3);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }

        BigDecimal partCount = BigDecimal.valueOf(reqVo.getPartCount());
        // 通知QMS_SY生成质检任务
        apsInformQmsService.assembleStartWork(reqVo.getPlmid(), oldAwo.getErpCode(), oldAwo.getMaterName(), partCount, apsOrder.getConstructNo(), reqVo.getPhaseCode(), reqVo.getStationCode(), reqVo.getStaffCode(), reqVo.getUniqueCode(), PkgUtils.gen(apsOrder.getSeq()));

//        qmsOldApiClient.assemblyWorkEnd(apsOrder.getConstructNo(), reqVo.getStationCode(), reqVo.getPlmid(), reqVo.getPhaseCode(), reqVo.getStaffCode(), reqVo.getUniqueCode());

    }

    public void checkStatus(ApsWorkOrder apsWorkOrder) {

        ApsOrder apsOrder = apsOrderMapper.selectById(apsWorkOrder.getApsOrderId());

        Order order = orderMapper.selectById(apsOrder.getOrderId());

        LambdaQueryChainWrapper<ApsWorkOrder> workOrderWrapper = apsWorkOrderMapper.lambdaQuery();
        workOrderWrapper.eq(ApsWorkOrder::getApsOrderId, apsWorkOrder.getApsOrderId());
        if(order.getOrderType().equals(1)){
            workOrderWrapper.ge(ApsWorkOrder::getLevel, 1);
        } else if(order.getOrderType().equals(4) || order.getOrderType().equals(3)){
            workOrderWrapper.gt(ApsWorkOrder::getLevel, 1);
        }
        workOrderWrapper.apply(" finish_count <> order_count");
//        Integer count = workOrderWrapper.count();
        List<ApsWorkOrder> list = workOrderWrapper.list();
        if (list.size() > 0) {
            return ;
        }
        apsOrder.setActualFinishTime(LocalDateTime.now());
        apsOrder.setOrderStatus(9);
        apsOrderMapper.updateById(apsOrder);

        List<ApsOrder> list1 = apsOrderMapper.lambdaQuery()
                .eq(ApsOrder::getOrderId, apsOrder.getOrderId())
                .apply(" order_qty <> finish_qty")
                .list();

        if(list1.size() > 0){
            return ;
        }

        order.setActualEndDateTime(LocalDateTime.now());
        order.setOrderStatus(9);
        orderMapper.updateById(order);

    }

    @Transactional
    public void matchStart(WorkshopMatchStartReqVo reqVo) {
        // 2。添加开报工日志
        partUtilService.startPartReport(reqVo.getTargetCode(), reqVo.getTargetCode(), 2, 1,
                reqVo.getMatchCode(), WorkshopProp.PP_PHASE_CODE, reqVo.getMatchCode(), 1,
                reqVo.getWorker(), null, null);
        matchTaskDetailMapper.lambdaUpdate()
                .eq(MatchDetailTask::getMatchCode, reqVo.getMatchCode())
                .eq(MatchDetailTask::getStatus, 1)
                .set(MatchDetailTask::getStatus, 2)
                .update();
    }

    /**
     * 与托盘强关联，前期暂时废除
     *
     * @param reqVo
     */
    @Transactional
    public void matchStart2(WorkshopMatchStartReqVo reqVo) {

        String[] split = {reqVo.getSourceCode()};
        if (reqVo.getSourceCode().contains(",")) {
            split = reqVo.getSourceCode().split(",");
        }

        List<String> plmIdList = new ArrayList<>();
        List<String> pllateList = new ArrayList<>();

        for (String s : split) {
            List<PartPallet> partPalletList = partPalletMapper.lambdaQuery()
                    .eq(PartPallet::getLoadingCode, s.trim())
                    .eq(PartPallet::getType, reqVo.getSourceType())
                    .list();

            for (PartPallet partPallet : partPalletList) {

                if (WorkshopProp.KJ_PHASE_CODE.equals(partPallet.getPhaseCode())) {
                    plmIdList.add(partPallet.getPlmId());
                    pllateList.add(partPallet.getLoadingCode());
                    partUtilService.putPartToStation(partPallet, reqVo.getTargetCode());
                    log.info("修改配载编号：" + partPallet.getPlmId() + " 成功");
                } else {
                    log.error("非KJ的零件不能配盘：托盘" + partPallet.getLoadingCode() + " 工序：" + partPallet.getPhaseCode());
                }

            }
        }

        if (CollUtil.isNotEmpty(plmIdList)) {
            wmsApiClient.clearPallet(pllateList);
            matchTaskDetailMapper.lambdaUpdate()
                    .in(MatchDetailTask::getMaterCode, plmIdList)
                    .eq(MatchDetailTask::getMatchCode, reqVo.getMatchCode())
                    .eq(MatchDetailTask::getStatus, 1)
                    .set(MatchDetailTask::getStatus, 2)
                    .update();
        }

    }

    @Transactional
    public void matchEnd(WorkshopMatchEndReqVo reqVo) {


        // 删除其他配单
        List<MatchPallet> matchList = matchPalletMapper.lambdaQuery().eq(MatchPallet::getPlateNo, reqVo.getPalletNumber()).list();
        if (!CollectionUtils.isEmpty(matchList)) {
            Map<String, List<MatchPallet>> collect1 = matchList.stream().collect(Collectors.groupingBy(MatchPallet::getMatchCode));
            for (String key : collect1.keySet()) {
                if (!org.apache.commons.lang3.StringUtils.equals(key, reqVo.getMatchcNo())) {
                    List<MatchPallet> matchPallets = collect1.get(key);
                    for (MatchPallet matchPallet : matchPallets) {
                        matchPalletMapper.deleteById(matchPallet.getId());
                    }
                }
            }
        }
        List<MatchTask> taskList = matchTaskMapper.lambdaQuery()
                .eq(MatchTask::getMatchCode, reqVo.getMatchcNo())
                .in(MatchTask::getStatus, 1, 2)
                .orderByAsc(MatchTask::getMatchDate)
                .list();
        if (CollectionUtils.isEmpty(taskList)) {
            throw SyExceptionUtils.e(String.format("配盘任务%s未找到待加工的任务", reqVo.getMatchcNo()));
//            String matchcNo = reqVo.getMatchcNo();
//            String[] s = matchcNo.split("_");
//            mbdPpJob(null, s[0]);
//
//            List<MatchTask> taskListRepeat = matchTaskMapper.lambdaQuery()
//                    .eq(MatchTask::getMatchCode, reqVo.getMatchcNo())
//                    .in(MatchTask::getStatus, 1, 2)
//                    .orderByAsc(MatchTask::getMatchDate)
//                    .list();
//            if (CollectionUtils.isEmpty(taskListRepeat)) {
//                throw SyExceptionUtils.e(String.format("配盘任务%s未找到待加工的任务", reqVo.getMatchcNo()));
//            }
        }
        List<WorkRecord> recordList = workRecordMapper.lambdaQuery().eq(WorkRecord::getOperationId, taskList.get(0).getId()).eq(WorkRecord::getWorkType, 1)
                .eq(WorkRecord::getPlmid, reqVo.getMatchcNo()).eq(WorkRecord::getType, 2).orderByDesc(WorkRecord::getId).list();
        Integer startId = null;
        LocalDateTime startTime = null;
        if (!CollectionUtils.isEmpty(recordList)) {
            startId = recordList.get(0).getId();
            startTime = recordList.get(0).getWorkTime();
        }
        reqVo.setWorker(StringUtils.hasText(reqVo.getWorker()) ? reqVo.getWorker() : SySecurityUtils.getUserCode());
        WorkRecord  workRecord=null;
        int matchCount = reqVo.getMatchcCount();
        for (MatchTask task : taskList) {
            if (matchCount < (task.getTotalCount() - task.getFinishCount())) {
                workRecord= partUtilService.complatePartReport(null, reqVo.getConstrNumber(), reqVo.getConstrNumber(), 2, 2, reqVo.getMatchcNo(),
                        WorkshopProp.PP_PHASE_CODE, reqVo.getPalletNumber(), matchCount, 0, reqVo.getWorker(), task.getId(), null, startId, startTime, null);
                task.setFinishCount(task.getFinishCount() + matchCount);
                matchCount = 0;
                task.setStatus(2);

            } else {
                workRecord=partUtilService.complatePartReport(null, reqVo.getConstrNumber(), reqVo.getConstrNumber(), 2, 2, reqVo.getMatchcNo(),
                        WorkshopProp.PP_PHASE_CODE, reqVo.getPalletNumber(), task.getTotalCount() - task.getFinishCount(), 0, reqVo.getWorker(), task.getId(), null, startId, startTime, null);
                matchCount = matchCount - (task.getTotalCount() - task.getFinishCount());
                task.setFinishCount(task.getTotalCount());
                task.setStatus(3);
            }
            matchTaskMapper.updateById(task);
            if (matchCount == 0) {
                break;
            }
        }
        if (matchCount > 0) {
            throw SyExceptionUtils.e("配盘任务报工数量超限");
        }

        for (WorkshopMatchEndDataReqVo partInfoDto : reqVo.getPartInfoDtos()) {
            int qty = partInfoDto.getPartCount() * reqVo.getMatchcCount();
            MatchDetailTaskLog log = new MatchDetailTaskLog();
            log.setPid(workRecord.getId());
            log.setPlmid(partInfoDto.getPlmid());
            log.setPartCount(partInfoDto.getPartCount());
            log.setTotalCount(qty);
            log.setPalletCode(reqVo.getPalletNumber());
            log.setStationCode(reqVo.getStorageNumber());
            log.setPhaseCode(WorkshopProp.KJ_PHASE_CODE);
            matchDetailTaskLogMapper.insert(log);
            MatchPallet mpallet = new MatchPallet();
            mpallet.setPlmId(partInfoDto.getPlmid());
            mpallet.setMatchDate(LocalDate.now());
            mpallet.setPlateNo(reqVo.getPalletNumber().toUpperCase());
            mpallet.setMaterName(partInfoDto.getPlmid());
            mpallet.setTotalCount(qty);
            mpallet.setMatchCode(reqVo.getMatchcNo());
            matchPalletMapper.insert(mpallet);


            List<MatchDetailTask> taskDetaiList = matchDetailTaskMapper.lambdaQuery()
                    .eq(MatchDetailTask::getMaterCode, partInfoDto.getPlmid())
                    .in(MatchDetailTask::getStatus, 1, 2)
                    .orderByAsc(MatchDetailTask::getMatchDate)
                    .list();

            int result = qty;
            for (MatchDetailTask matchDetailTask : taskDetaiList) {
                if (result < (matchDetailTask.getTotalCount() - matchDetailTask.getFinishCount())) {
                    matchDetailTask.setFinishCount(matchDetailTask.getFinishCount() + result);
                    result = 0;
                    matchDetailTask.setStatus(2);
                } else {
                    result = result - (matchDetailTask.getTotalCount() - matchDetailTask.getFinishCount());
                    matchDetailTask.setFinishCount(matchDetailTask.getTotalCount());
                    matchDetailTask.setStatus(3);
                }
                matchDetailTaskMapper.updateById(matchDetailTask);
                if (result == 0) {
                    break;
                }
            }
            /*if (result > 0) {
                throw SyExceptionUtils.e("配盘报工数量超限：{}", partInfoDto.getPlmid());
            }*/
        }
    }

    /**
     * 该方法与托盘强关联，前期先进行废除
     *
     * @param reqVo
     */
    /*@Transactional
    public void matchEnd2(WorkshopMatchEndReqVo reqVo) {


        // 增加配盘报工记录
        WorkRecord workRecord = new WorkRecord();
        workRecord.setType(2);
        workRecord.setErpState(0);
        workRecord.setWorkType(2);
        workRecord.setPlmid(reqVo.getMatchcNo());
        workRecord.setPhaseCode(WorkshopProp.PP_PHASE_CODE);
        workRecord.setStationCode(reqVo.getConstrNumber());
        workRecord.setWorkTime(LocalDateTime.now());
        workRecord.setStorageNumber(reqVo.getStorageNumber());
        workRecord.setPalletNumber(reqVo.getPalletNumber());
        workRecord.setWorkStaffCode(reqVo.getWorker());
        workRecord.setTotalCount(reqVo.getMatchcCount());
        workRecord.setSuccessCount(reqVo.getMatchcCount());
        workRecord.setFailCount(0);
        workRecordMapper.insert(workRecord);

        for (WorkshopMatchEndDataReqVo partInfoDto : reqVo.getPartInfoDtos()) {

            int qty = partInfoDto.getPartCount() * reqVo.getMatchcCount();


            PartPallet partPallet = partPalletMapper.lambdaQuery()
                    .eq(PartPallet::getType, 3)
                    .eq(PartPallet::getPositionCode, reqVo.getStorageNumber())
                    .eq(PartPallet::getPlmId, partInfoDto.getPlmid())
                    .eq(PartPallet::getPhaseCode, WorkshopProp.KJ_PHASE_CODE)
                    .one();

            if (partPallet == null) {
                throw SyExceptionUtils.e("该工位上没有此零件:{}", partInfoDto.getPlmid());
            }

            Part part = partMapper.lambdaQuery()
                    .eq(Part::getPartType, 2)
                    .eq(Part::getPlmId, partInfoDto.getPlmid())
                    .eq(Part::getPhaseCode, WorkshopProp.KJ_PHASE_CODE)
                    .one();

            MatchDetailTaskLog log = new MatchDetailTaskLog();
            log.setPid(workRecord.getId());
            log.setPlmid(partInfoDto.getPlmid());
            log.setPartCount(partInfoDto.getPartCount());
            log.setTotalCount(qty);
            log.setPalletCode(reqVo.getPalletNumber());
            log.setStationCode(reqVo.getStorageNumber());
            log.setPhaseCode(part.getPhaseCode());
            log.setPrePhaseCode(part.getPrePhaseCode());
            matchDetailTaskLogMapper.insert(log);
            // 工位扣减
            partUtilService.reducePartFromPallet(partPallet, qty, true);
            // 托盘新增
            partUtilService.putMultiplePallet(qty, reqVo.getPalletNumber(), part);

            List<MatchDetailTask> taskList = matchDetailTaskMapper.lambdaQuery()
                    .eq(MatchDetailTask::getMaterCode, partInfoDto.getPlmid())
                    .in(MatchDetailTask::getStatus, 1, 2)
                    .orderByAsc(MatchDetailTask::getMatchDate)
                    .list();

            int result = qty;
            for (MatchDetailTask matchDetailTask : taskList) {
                if (result < (matchDetailTask.getTotalCount() - matchDetailTask.getFinishCount())) {
                    matchDetailTask.setFinishCount(matchDetailTask.getFinishCount() + result);
                    result = 0;
                    matchDetailTask.setStatus(2);
                } else {
                    result = result - (matchDetailTask.getTotalCount() - matchDetailTask.getFinishCount());
                    matchDetailTask.setFinishCount(matchDetailTask.getTotalCount());
                    matchDetailTask.setStatus(3);
                }
                matchDetailTaskMapper.updateById(matchDetailTask);
                if (result == 0) {
                    break;
                }
            }
            if (result > 0) {
                throw SyExceptionUtils.e("数量不够");
            }
        }

    }*/
    public BaseListResVo<WorkshopPpHistoryResVo> ppHistory(WorkshopPpHistoryReqVo reqVo) {
        List<WorkshopPpHistoryResVo> collect = matchDetailTaskLogMapper.lambdaQuery()
                .eq(MatchDetailTaskLog::getPalletCode, reqVo.getPalletCode())
                .orderByDesc(BaseEntity::getCreateDateTime)
                .last(" limit 10")
                .list()
                .stream()
                .map(e -> {
                    WorkshopPpHistoryResVo resVo = new WorkshopPpHistoryResVo();
                    resVo.setPackageNo(e.getPalletCode());
                    resVo.setPartNo(e.getPlmid());
                    resVo.setPartCount(e.getPartCount());
                    resVo.setNextWorkPhase(e.getPrePhaseCode());
                    resVo.setNextTwoWorkPhase(e.getPhaseCode());
                    return resVo;
                })
                .collect(Collectors.toList());

        return new BaseListResVo<>(collect);
    }


    /**
     * 钢板施工信息
     */

    public String maxCode(String plmid, String construction) {
        QueryWrapper<WorkDetailTask> wrapper = Wrappers.query();
        wrapper.eq("awd.mater_no", plmid);
        wrapper.eq("o.construct_no", construction);
        wrapper.ne("awd.unique_code", "PD");
        return workDetailTaskMapper.selectMaxCode(wrapper);
    }


    public void palletCleanNoWms(WorkshopPalletCleanNoThirdReqVo reqVo) {
        LambdaQueryWrapper<PartPallet> query = new LambdaQueryWrapper<>();
        query.eq(PartPallet::getLoadingCode, reqVo.getPalletCode());
        if (org.apache.commons.lang.StringUtils.isNotBlank(reqVo.getPlmid())) {
            query.eq(PartPallet::getPlmId, reqVo.getPlmid());
        }
        List<PartPallet> partPallets = partPalletMapper.selectList(query);
        for (PartPallet pp : partPallets) {
            //wms调用，不需要进行回调
            partUtilService.reducePartFromPallet(pp, pp.getPartCount(), false);
        }
    }

    public void packMerge(WorkshopPackMergeReqVo reqVo) {
        List<PartPallet> oldList = partPalletMapper.lambdaQuery()
                .eq(PartPallet::getType, 1)
                .eq(PartPallet::getLoadingCode, reqVo.getInitialPallet())
                .list();
        if (CollectionUtils.isEmpty(oldList)) {
            return;
        } else if (oldList.size() > 1) {
            if (reqVo.getStorageNumber() != null && reqVo.getStorageNumber().contains("buffer")) {
            } else {
                String prePlimd = oldList.get(0).getPlmId();
                String prePhase = oldList.get(0).getPhaseCode();
                for (int i = 1; i < oldList.size(); i++) {
                    if (!prePlimd.equals(oldList.get(i).getPlmId())) {
                        throw SyExceptionUtils.e(String.format("合盘失败,起始托盘%s,plmid不一致，并且工序不是", reqVo.getInitialPallet()));
                    } else if (!prePhase.equals(oldList.get(i).getPhaseCode())) {
                        throw SyExceptionUtils.e(String.format("合盘失败,起始托盘%s,plmid一致，工序不一致", reqVo.getInitialPallet()));
                    }
                }
            }

        }
        for (PartPallet oldPallet : oldList) {
            Part part = partService.getPart(oldPallet.getConstructNo(), oldPallet.getPlmId(), oldPallet.getPhaseCode());
            if (part == null) {
                throw SyExceptionUtils.e("无此零件{}工序{}上道工序{}", oldPallet.getPlmId(), oldPallet.getPhaseCode(), oldPallet.getPrePhaseCode());
            }
            partUtilService.putPallet(oldPallet.getPartCount(), reqVo.getDestinationPallet(), part);
            partPalletMapper.deleteReal(oldPallet.getId());
        }


    }

    @Transactional
    public void trayBind(WorkshopTrayBindReqVo reqVo) {
        PartPallet pp = partPalletMapper.lambdaQuery()
                .eq(PartPallet::getPlmId, reqVo.getPlmId())
                .eq(PartPallet::getLoadingCode, reqVo.getTrayCode())
                .eq(PartPallet::getPhaseCode, WorkshopProp.KJ_PHASE_CODE)
                .eq(PartPallet::getType, 1)
                .eq(PartPallet::getPartType, 2)
                //.eq(PartPallet::getPackingImg, reqVo.getPackingImg())
                .one();
        if (ObjectUtils.isEmpty(pp)) {
            throw SyExceptionUtils.e("托盘%s 未找到零件%s!", reqVo.getTrayCode(), reqVo.getPlmId());
        }
        partUtilService.putPartToStation(pp, reqVo.getStationCode());
      /*  if(pp != null && !pp.getLoadingCode().equals(reqVo.getTrayCode())){
            throw SyExceptionUtils.e("该托盘已绑定,并且绑定的不是该托盘!");
        }

        pp = new PartPallet();
        pp.setPlmId(reqVo.getPlmId());
        pp.setPhaseCode(WorkshopProp.KJ_PHASE_CODE);
        pp.setPartCount(0);
        pp.setPackingImg(reqVo.getPackingImg());
        pp.setLoadingCode(reqVo.getTrayCode());
        pp.setType(1);
        pp.setPartType(2);
        partPalletMapper.insert(pp);*/

    }

    @Transactional
    public void trayUnbind(WorkshopTrayUnbindReqVo reqVo) {
        PartPallet pp = partPalletMapper.lambdaQuery()
                .eq(PartPallet::getPlmId, reqVo.getPlmId())
                .eq(PartPallet::getPhaseCode, WorkshopProp.KJ_PHASE_CODE)
                .eq(PartPallet::getType, 1)
                .eq(PartPallet::getPartType, 2)
                .eq(PartPallet::getPackingImg, reqVo.getPackingImg())
                .one();
        if (pp != null) {
            partPalletMapper.deleteReal(pp.getId());
        }
    }

/*    public void clearplate() {

        List<Part> list = partMapper.lambdaQuery().eq(Part::getPartType, 1).list();
        for (Part p : list) {
            Plate plate = plateMapper.lambdaQuery().eq(Plate::getMaterCode, p.getPlmId()).one();

            List<SinoCamReceiveNestPart> nestPartList = sinoCamReceiveNestPartMapper.lambdaQuery()
                    .apply("receive_nest_id in (select receive_nest_id from tb_third_sinocam_receive_nest_plate where stock_list_no={0})", plate.getMaterCode())
                    .list();
            List<SinoCamReceiveNestPart> collect = nestPartList.stream().filter(e -> e.getQuantity() != e.getSortingCount().intValue()).collect(Collectors.toList());
            if (collect.isEmpty()) {

                PartPallet pp = partPalletMapper.lambdaQuery().eq(PartPallet::getPlmId, p.getPlmId()).eq(PartPallet::getPartType, 1).one();
                if (pp != null) {
                    log.info("钢板分拣完成，删除托架上的钢板" + p.getPlmId());
                    partPalletMapper.deleteReal(pp.getId());
                }
                if (p != null) {
                    log.info("钢板分拣完成，删除钢板" + p.getPlmId());
                    partMapper.deleteReal(p.getId());
                }
                plate.setStatus(6);
                plateMapper.updateById(plate);


            }
        }


    }*/

/*    public void sysWms() {
        // 通知wms组件报工
        PartsReportingAddDto partReport = apsWorkDetailMapper.getAssePartInfo(41971);
        if (!ObjectUtils.isEmpty(partReport)) {
            partReport.setWorkPlace("WorkPlace");
            partReport.setWorkers("WorkPlace");
            partReport.setNxphase("PH");
            wmsApiClient.AsseSyc(partReport);
        }
    }*/

    public BasePageResVo<PlatePartListResVo> platePartEndList(WorkshopPlatePartListReqVo reqVo) {
        Group group = groupMapper.selectById(reqVo.getId());
        QueryWrapper<SinoCamReceiveNestPart> query = Wrappers.query();
        query.eq("mwr.type", 2);
        query.eq("mwr.STATUS", 3);
        query.eq("mwr.phase_code", WorkshopProp.FJ_PHASE_CODE);
        if (group != null) {
            query.eq(" mwr.group_code", group.getMyCode());
        } else {
            query.eq(org.springframework.util.StringUtils.hasText(reqVo.getGroupCode()), " mwr.group_code", reqVo.getGroupCode());
        }
        if (StringUtils.hasText(reqVo.getPlateCode())) {
            query.like(" plate.stock_list_no", reqVo.getPlateCode());
        }
        if (StringUtils.hasText(reqVo.getMaterName())) {
            query.like(" part.part_name", reqVo.getMaterName());
        }
        if (StringUtils.hasText(reqVo.getConstructNo())) {
            query.like("ao.construct_no", reqVo.getConstructNo());
        }
        query.like(org.springframework.util.StringUtils.hasText(reqVo.getMaterCode()), " mwr.mater_code ", reqVo.getMaterCode());
        query.orderByDesc("mwr.id");
        Page<PlatePartListResVo> list = sinoCamReceiveNestPartMapper.platePartEndList(reqVo.toPage(), query);
        for (PlatePartListResVo e : list.getRecords()) {
            e.setDimension(String.format("%s * %s * %s", e.getLength() == null ? "-" : e.getLength(), e.getWidth() == null ? "-" : e.getWidth(), e.getThickness() == null ? "-" : e.getThickness()));
//            e.setDrawing(WorkshopProp.NESTING_DRAWING_CTX + e.getDrawing());
            e.setDrawing(e.getDrawing());
//            e.setPlatePdfUrl(WorkshopProp.NESTING_DRAWING_CTX + e.getPlatePdfUrl());
            e.setPlatePdfUrl(e.getPlatePdfUrl());
            e.setPhaseCode(WorkshopProp.FJ_PHASE_CODE);

            if (StringUtils.hasText(e.getDrawing())) {
                e.setDrawing(String.format(projectConfig.getUrlPre(), e.getMaterCode() + ".png", e.getDrawing()));
            }

        }

        BasePageResVo<PlatePartListResVo> resVo = new BasePageResVo<>(list.getTotal(), list.getRecords());

        for (PlatePartListResVo datum : resVo.getData()) {
            if (datum.getSplitNum() != null) {
                datum.setPkgCode(PkgUtils.gen(datum.getSplitNum()));
            }

            // 开始分捡后的下一道工序
            QueryWrapper<ApsWorkDetail> query1 = Wrappers.query();
            query1.eq("aps_work_order_id", datum.getApsWorkOrderId());
            query1.gt("phase_seq", datum.getPhaseSeq());
            Integer minPhaseSeq = apsWorkDetailMapper.minPhaseSeq(query1);
            if (minPhaseSeq != null) {
                ApsWorkDetail nextList = apsWorkDetailMapper.lambdaQuery()
                        .eq(ApsWorkDetail::getApsWorkOrderId, datum.getApsWorkOrderId())
                        .gt(ApsWorkDetail::getPhaseSeq, minPhaseSeq)
                        .orderByAsc(ApsWorkDetail::getPhaseSeq)
                        .last(" limit 1")
                        .one();

                if (nextList != null) {
                    datum.setNextGroupCode(nextList.getGroupCode());
                    datum.setNextPhaseCode(nextList.getPhaseCode());
                }
            }
            datum.setPlateName("钢板");
        }
        return resVo;
    }

    public void assembleYipingStart(WorkshopAssembleStartReqVo reqVo) {
        List<ApsWorkDetail> apsWorkDetails = null;
        Station station = stationMapper.lambdaQuery().eq(Station::getMyCode, reqVo.getStationCode()).one();
        Group group = null;
        if (ObjectUtils.isEmpty(station)) {
            group = groupMapper.selectOne(new QueryWrapper<Group>().eq("my_code", reqVo.getStationCode()));
        } else {
            group = groupMapper.selectGroupByStation(station.getId());
        }
        if(StringUtils.hasText(reqVo.getConstructNo())){
            QueryWrapper<ApsWorkDetail> wrapper = Wrappers.query();
            wrapper.eq("wd.mater_no", reqVo.getAssemblyNumber());
            wrapper.eq("wd.group_code", group.getMyCode());
            wrapper.eq("wd.phase_code", WorkshopProp.PZ_PHASE_CODE);
            wrapper.lt("wd.status", 3);
            wrapper.eq("wd.deleted", 0);
            wrapper.eq("tbo.construct_no", reqVo.getConstructNo());
            apsWorkDetails = apsWorkDetailMapper.selectDetailByOrder(wrapper);
            if(!CollectionUtils.isEmpty(apsWorkDetails)){
                apsWorkOrderMapper.lambdaUpdate().set(ApsWorkOrder::getActualStartDateTime, LocalDateTime.now())
                        .isNull(ApsWorkOrder::getActualStartDateTime)
                        .in(ApsWorkOrder::getId, apsWorkDetails.stream().map(ApsWorkDetail::getApsWorkOrderId).collect(Collectors.toList()))
                        .update();

                boolean update = apsWorkDetailMapper.lambdaUpdate().set(ApsWorkDetail::getStatus, 3)
                        .set(ApsWorkDetail::getActualStartDateTime, LocalDateTime.now())
                        .in(ApsWorkDetail::getId, apsWorkDetails.stream().map(ApsWorkDetail::getId).collect(Collectors.toList()))
                        .lt(ApsWorkDetail::getStatus, 3).update();
            }
            return;
        }else if (reqVo.getApsWorkOrderId() != null) {
            apsWorkDetails = apsWorkDetailMapper.lambdaQuery()
                    .eq(ApsWorkDetail::getApsWorkOrderId, reqVo.getApsWorkOrderId())
                    .eq(ApsWorkDetail::getStatus, 2)
                    .list();

        } else {
            ApsWorkDetail apsWorkDetail = apsWorkDetailMapper.lambdaQuery()
                    .eq(ApsWorkDetail::getMaterNo, reqVo.getAssemblyNumber())
                    .eq(!ObjectUtils.isEmpty(group), ApsWorkDetail::getGroupId, group != null ? group.getId() : null)
                    .eq(ApsWorkDetail::getStatus, 2)// 待开工 如果2,3的话会总是更新第一条数据
                    .orderByAsc(ApsWorkDetail::getApsOrderId)
                    .last("limit 1")
                    .one();
            if (!ObjectUtils.isEmpty(apsWorkDetail)) {
                reqVo.setApsWorkOrderId(apsWorkDetail.getApsWorkOrderId());
                apsWorkDetails = apsWorkDetailMapper.lambdaQuery()
                        .eq(ApsWorkDetail::getApsWorkOrderId, apsWorkDetail.getApsWorkOrderId())
                        .eq(ApsWorkDetail::getStatus, 2)
                        .list();
            }
        }
/*        ApsWorkOrder apsWorkOrder = apsWorkOrderMapper.selectById(reqVo.getApsWorkOrderId());
        if (apsWorkOrder.getActualStartDateTime() == null) {
            apsWorkOrder.setActualStartDateTime(LocalDateTime.now());
            apsWorkOrderMapper.updateById(apsWorkOrder);
        }
        for (ApsWorkDetail apsWorkDetail : apsWorkDetails) {
            if (apsWorkDetail.getStatus() == 2) {
                apsWorkDetail.setStatus(3);
                apsWorkDetail.setActualStartDateTime(LocalDateTime.now());
                apsWorkDetailMapper.updateById(apsWorkDetail);

            }
        }*/
        if(!CollectionUtils.isEmpty(apsWorkDetails)){
            apsWorkOrderMapper.lambdaUpdate().set(ApsWorkOrder::getActualStartDateTime, LocalDateTime.now())
                    .isNull(ApsWorkOrder::getActualStartDateTime)
                    .eq(ApsWorkOrder::getId, reqVo.getApsWorkOrderId())
                    .update();

            boolean update = apsWorkDetailMapper.lambdaUpdate().set(ApsWorkDetail::getStatus, 3)
                    .set(ApsWorkDetail::getActualStartDateTime, LocalDateTime.now())
                    .in(ApsWorkDetail::getId, apsWorkDetails.stream().map(ApsWorkDetail::getId).collect(Collectors.toList()))
                    .lt(ApsWorkDetail::getStatus, 3).update();
        }


    }

    public WorkshopGetPickDetailResVo getPickDetail(WorkshopGetPickDetailReqVo reqVo) {
        // 领料单
        Pick pick = pickMapper.lambdaQuery()
                .eq(Pick::getPickCode, reqVo.getPickCode())
                .one();
        if (pick == null) {
            return null;
        }

        // 领料单钢板
        List<WmsPlatePick> plates = wmsPlatePickMapper.lambdaQuery()
                .eq(WmsPlatePick::getPickId, pick.getId())
                .list();
        if (plates.isEmpty()) {
            return null;
        }

        // 领料单钢板零件信息
        QueryWrapper<WorkshopNestPart> query = new QueryWrapper<>();
        query.in("part.plate_code", plates.stream().map(WmsPlatePick::getMaterialId).collect(Collectors.toList()));
        Map<String, List<WorkshopGetPickDetailResVo.NestItemInfo>> nestParts = workshopMapper.listPlatePart(query)
                .stream()
                .collect(Collectors.groupingBy(WorkshopNestPart::getPlateCode, Collectors.mapping(part -> {
                    WorkshopGetPickDetailResVo.NestItemInfo nestPart = new WorkshopGetPickDetailResVo.NestItemInfo();
                    nestPart.setName(part.getPartId());
                    nestPart.setConstructNo(part.getConstructNo());
                    nestPart.setConstructOrderNo(part.getWorkOrderCode());
                    nestPart.setCount(part.getQuantity());
                    nestPart.setPartWeight(part.getNetWeight() == null ? null : part.getNetWeight().floatValue());
                    return nestPart;
                }, Collectors.toList())));

        // 领料单钢板余料


        WorkshopGetPickDetailResVo resVo = new WorkshopGetPickDetailResVo();
        resVo.setPickingListNo(Integer.parseInt(pick.getPickCode().replaceAll("\\D", "")));
        resVo.setWantedDeliveryDate(plates.get(0).getWantDeliverDate());
        List<WorkshopGetPickDetailResVo.NestPlateInfo> nestPlateInfoList = plates.stream().map(plate -> {
            WorkshopGetPickDetailResVo.NestPlateInfo nestPlate = new WorkshopGetPickDetailResVo.NestPlateInfo();
            nestPlate.setPickListItemNo(plate.getPickListItem());
            nestPlate.setType(plate.getType());
            nestPlate.setStoragePlace(plate.getStoragePlace());
            nestPlate.setSequence(plate.getSeq());
            nestPlate.setAmount(plate.getAmount());
            nestPlate.setLength(plate.getLength() == null ? null : plate.getLength().floatValue());
            nestPlate.setWidth(plate.getWidth() == null ? null : plate.getWidth().floatValue());
            nestPlate.setNesting(plate.getNestId());
            nestPlate.setMaterialId(plate.getMaterialId());
            nestPlate.setNextWorkPlace(plate.getNextWorkPlace());
            nestPlate.setPlateUsage(plate.getPlateUsage() == null ? null : plate.getPlateUsage().floatValue());
            nestPlate.setPlateWeight(plate.getPlateWeight() == null ? null : plate.getPlateWeight().floatValue());
            nestPlate.setParts(nestParts.get(plate.getMaterialId()));
            nestPlate.setRemnant(null); // 暂不需要
            return nestPlate;
        }).collect(Collectors.toList());
        resVo.setNestPlateInfoList(nestPlateInfoList);
        return resVo;
    }

    public List<SprayMesMaterialDto> getSprayMesMateria() {
        List<SprayMesMaterialDto> ptTask = apsWorkDetailMapper.findSprayMesMaterialDto(WorkshopProp.PT_GROUP);
        if (!CollectionUtils.isEmpty(ptTask)) {
            Set<String> plmList = ptTask.stream().map(SprayMesMaterialDto::getAssemblyNumber).collect(Collectors.toSet());
            Map<String, AssemblyInfo> sizeInfo = mbdFeign.getSizeInfo(plmList);
            ptTask.forEach(item -> {
                AssemblyInfo ai = sizeInfo.get(item.getAssemblyNumber());
                SprayMesAssemblyInfo assemblyInfo = new SprayMesAssemblyInfo();
                assemblyInfo.setAssemblyNumber(ai.getAssemblyNumber());
                assemblyInfo.setLength(new BigDecimal(StringUtils.hasText(ai.getLength()) ? ai.getLength() : "0").intValue());
                assemblyInfo.setWidth(new BigDecimal(StringUtils.hasText(ai.getWidth()) ? ai.getWidth() : "0").intValue());
                assemblyInfo.setHeight(new BigDecimal(StringUtils.hasText(ai.getHeight()) ? ai.getHeight() : "0").intValue());
                assemblyInfo.setWeight(new BigDecimal(StringUtils.hasText(ai.getWeight()) ? ai.getWeight() : "0").intValue());
                item.setAssemblyInfo(assemblyInfo);
            });
        }
        return ptTask;
    }

    public void PartFjTaskCreate(String plate) {//dddd
        List<SinoCamReceiveNestPart> nestPartList = sinoCamReceiveNestPartMapper.lambdaQuery()
                .eq(SinoCamReceiveNestPart::getPlateCode, plate)
                .list();
        for (SinoCamReceiveNestPart nestPart : nestPartList) {
            if (nestPart.getSortingCount() >= nestPart.getQuantity()) {
                continue;
            }
            ApsWorkDetail qgApsWorkDetail = apsWorkDetailMapper.lambdaQuery()
                    .eq(ApsWorkDetail::getId, nestPart.getNestPlanId())
                    .one();
            ApsOrder apsOrder = apsOrderMapper.selectById(qgApsWorkDetail.getApsOrderId());
            int qgcount = nestPart.getQuantity() - nestPart.getSortingCount();
            List<ApsWorkDetail> fjWorkDetails = apsWorkDetailMapper.lambdaQuery().eq(ApsWorkDetail::getApsWorkOrderId, qgApsWorkDetail.getApsWorkOrderId()).eq(ApsWorkDetail::getPhaseCode, WorkshopProp.FJ_PHASE_CODE).list();
            for (ApsWorkDetail fjWorkDetail : fjWorkDetails) {
                if (qgcount == 0) {
                    break;
                }
                if (fjWorkDetail.getFinishCount() == null) {
                    fjWorkDetail.setFinishCount(new BigDecimal(0));
                }
                String staffCode = SySecurityUtils.getUserCode();
                Part oldpart = partService.getPart(apsOrder.getConstructNo(), nestPart.getPartId(), WorkshopProp.FJ_PHASE_CODE);
                if (fjWorkDetail.getTotalCount().subtract(fjWorkDetail.getFinishCount()).intValue() >= qgcount) {
                    WorkRecord workRecord = partUtilService.complatePartReport(apsOrder.getConstructNo(), fjWorkDetail.getGroupCode(), fjWorkDetail.getGroupCode(), 2, 2,
                            qgApsWorkDetail.getMaterNo(), WorkshopProp.FJ_PHASE_CODE, plate, qgcount, 0,
                            staffCode, null, fjWorkDetail.getId(), null, null, null);
                    try {
                        partUtilService.consumePart(oldpart, qgcount, fjWorkDetail.getGroupCode(), staffCode, workRecord.getId(), plate);
                    } catch (Exception e) {
                    }
                    this.fjPartDeal(fjWorkDetail, qgcount);
                    fjWorkDetail.setFinishCount(fjWorkDetail.getFinishCount().add(new BigDecimal(qgcount)));
                    qgcount = 0;
                } else {
                    WorkRecord workRecord = partUtilService.complatePartReport(apsOrder.getConstructNo(), fjWorkDetail.getGroupCode(), fjWorkDetail.getGroupCode(), 2, 2,
                            qgApsWorkDetail.getMaterNo(), WorkshopProp.FJ_PHASE_CODE, plate, fjWorkDetail.getTotalCount().subtract(fjWorkDetail.getFinishCount()).intValue(), 0,
                            staffCode, null, fjWorkDetail.getId(), null, null, null);
                    try {
                        partUtilService.consumePart(oldpart, qgcount, fjWorkDetail.getGroupCode(), staffCode, workRecord.getId(), plate);
                    } catch (Exception e) {
                    }
                    this.fjPartDeal(fjWorkDetail, fjWorkDetail.getTotalCount().subtract(fjWorkDetail.getFinishCount()).intValue());
                    qgcount = qgcount - (fjWorkDetail.getTotalCount().subtract(fjWorkDetail.getFinishCount()).intValue());
                    fjWorkDetail.setFinishCount(fjWorkDetail.getTotalCount());
                }
                fjWorkDetail.setActualStartDateTime(LocalDateTime.now());
                if (fjWorkDetail.getFinishCount().compareTo(fjWorkDetail.getTotalCount()) >= 0) {
                    fjWorkDetail.setActualEndDateTime(LocalDateTime.now());
                    fjWorkDetail.setStatus(4);
                } else {
                    fjWorkDetail.setStatus(3);
                }
                apsWorkDetailMapper.updateById(fjWorkDetail);

            }
            nestPart.setSortingCount(nestPart.getQuantity());
            sinoCamReceiveNestPartMapper.updateById(nestPart);

        }
    }

    public void fjPartDeal(ApsWorkDetail fj, Integer currentReport) {
        // 获取工序最小序号
        QueryWrapper<ApsWorkDetail> query = Wrappers.query();
        query.eq("aps_work_order_id", fj.getApsWorkOrderId());
        query.eq("mater_no", fj.getMaterNo());
        query.gt("phase_seq", fj.getPhaseSeq());
        query.orderByAsc("phase_seq");
        query.last("LIMIT 1");
        String nextPhase = apsWorkDetailMapper.nextPhase(query);

        ApsWorkOrder apsWorkOrder = apsWorkOrderMapper.selectById(fj.getApsWorkOrderId());
        ApsOrder apsOrder = apsOrderMapper.lambdaQuery().eq(ApsOrder::getId, apsWorkOrder.getApsOrderId()).one();
        if (StringUtils.hasText(nextPhase) && !nextPhase.equals(WorkshopProp.KJ_PHASE_CODE)) {
            List<ApsWorkDetail> nextList = apsWorkDetailMapper.lambdaQuery()
                    .eq(ApsWorkDetail::getMaterNo, fj.getMaterNo())
                    .eq(ApsWorkDetail::getApsWorkOrderId, fj.getApsWorkOrderId())
                    .in(ApsWorkDetail::getStatus, 2, 3)
                    .eq(ApsWorkDetail::getPhaseCode, nextPhase)
                    .orderByAsc(ApsWorkDetail::getStatus)
                    .list();
            if (nextList.isEmpty()) {
                return;
            }
            try {
                partUtilService.makeWorkDetailTask(new WorkDetailTask(), nextList.get(0), currentReport, WorkshopProp.FJ_PHASE_CODE, new SinoCamReceiveNestPart());
                partUtilService.createPart(apsOrder.getConstructNo(), fj.getMaterNo(), fj.getPhaseSeq(), fj.getPhaseCode(), nextList.get(0).getPhaseCode(), nextList.get(0).getPhaseName(), apsWorkOrder.getWorkChain(), nextList.get(0).getGroupCode(), currentReport, 0);
            } catch (Exception e) {
                return;
            }
        } else {
            //  如果是最后一道工序  或者是库检

            Part nextPart = partUtilService.createPart(apsOrder.getConstructNo(), apsWorkOrder.getPlmId(), fj.getPhaseSeq(), fj.getPhaseCode(), WorkshopProp.KJ_PHASE_CODE, WorkshopProp.KJ_PHASE_CODE, apsWorkOrder.getWorkChain(), null, currentReport, 0);
            //零件装盘
            apsWorkOrder.setFinishCount(apsWorkOrder.getFinishCount().add(new BigDecimal(currentReport)));
            if (apsWorkOrder.getOrderCount().intValue() <= apsWorkOrder.getFinishCount().intValue()) {
                apsWorkOrder.setActualEndDateTime(LocalDateTime.now());
                apsWorkOrder.setStatus(4);
                apsWorkOrderMapper.updateById(apsWorkOrder);
            } else {
                apsWorkOrderMapper.updateById(apsWorkOrder);
            }

            if (apsWorkOrder.getPid() == null) {
                apsOrder.setFinishQty(apsOrder.getFinishQty() + currentReport);
                if (apsOrder.getOrderQty().equals(apsOrder.getFinishQty())) {
                    apsOrder.setOrderStatus(9);
                    apsOrder.setActualFinishTime(LocalDateTime.now());
                }
                apsOrderMapper.updateById(apsOrder);
                Order order = orderMapper.selectById(apsOrder.getOrderId());
                order.setFinishQty(order.getFinishQty() + currentReport);
                // 再判断是否所有的子订单都完成，如果
                Integer count = apsOrderMapper.lambdaQuery()
                        .eq(ApsOrder::getOrderId, apsOrder.getOrderId())
                        .ne(ApsOrder::getOrderStatus, 9)
                        .count();
                if (count == 0) {
                    order.setOrderStatus(9);
                    order.setActualEndDateTime(LocalDateTime.now());
                }
                orderMapper.updateById(order);
            }

        }

    }

    @Transactional
    public void fixPartTaskCreate(String plate, String orderId) {
        WorkshopPlateEndWorkReqVo reqVo = new WorkshopPlateEndWorkReqVo();
        reqVo.setPlateCode(plate);
        List<SinoCamReceiveNestPart> nestPartList = sinoCamReceiveNestPartMapper.lambdaQuery()
                .eq(SinoCamReceiveNestPart::getPlateCode, plate)
                .in(SinoCamReceiveNestPart::getId, 80858,80859,80860,80861,80862)
                //.likeRight(SinoCamReceiveNestPart::getUniCode, orderId + "#")
                .list();
        WorkDetailTask yc = workDetailTaskMapper.lambdaQuery()
                .eq(WorkDetailTask::getMaterCode, plate)
                .eq(WorkDetailTask::getStatus, 3)
                .eq(WorkDetailTask::getType, 1)
                .eq(WorkDetailTask::getPhaseCode, "YC")
                .one();
        if (ObjectUtils.isEmpty(yc)) {
            return;
        }


        if (org.apache.commons.lang3.StringUtils.equals(yc.getPhaseCode(), WorkshopProp.YC_PHASE_CODE)) {
            for (SinoCamReceiveNestPart nestPart : nestPartList) {
                ApsWorkDetail qgApsWorkDetail = apsWorkDetailMapper.lambdaQuery()
                        .eq(ApsWorkDetail::getId, nestPart.getNestPlanId())
                        .one();
                int qgcount = nestPart.getQuantity();
                List<ApsWorkDetail> ycWorkDetails = apsWorkDetailMapper.lambdaQuery().eq(ApsWorkDetail::getApsWorkOrderId, qgApsWorkDetail.getApsWorkOrderId()).eq(ApsWorkDetail::getPhaseCode, WorkshopProp.YC_PHASE_CODE).list();
                for (ApsWorkDetail ycWorkDetail : ycWorkDetails) {
                    if (qgcount == 0) {
                        break;
                    }
                    if (ycWorkDetail.getFinishCount() == null) {
                        ycWorkDetail.setFinishCount(new BigDecimal(0));
                    }
                    Order one = orderMapper.lambdaQuery().eq(Order::getId, ycWorkDetail.getOrderId()).one();
                    if (ycWorkDetail.getTotalCount().subtract(ycWorkDetail.getFinishCount()).intValue() >= qgcount) {
                        this.createPartReport(one.getConstructNo(), yc.getGroupCode(), ycWorkDetail, yc.getPhaseCode(), new BigDecimal(qgcount), reqVo);
                        ycWorkDetail.setFinishCount(ycWorkDetail.getFinishCount().add(new BigDecimal(qgcount)));
                        qgcount = 0;

                    } else {
                        this.createPartReport(one.getConstructNo(), yc.getGroupCode(), ycWorkDetail, yc.getPhaseCode(), ycWorkDetail.getTotalCount().subtract(ycWorkDetail.getFinishCount()), reqVo);
                        qgcount = qgcount - (ycWorkDetail.getTotalCount().subtract(ycWorkDetail.getFinishCount()).intValue());
                        ycWorkDetail.setFinishCount(ycWorkDetail.getTotalCount());
                    }
                    ycWorkDetail.setActualStartDateTime(LocalDateTime.now());
                    if (ycWorkDetail.getFinishCount().compareTo(ycWorkDetail.getTotalCount()) >= 0) {
                        ycWorkDetail.setActualEndDateTime(LocalDateTime.now());
                        ycWorkDetail.setStatus(4);
                    } else {
                        ycWorkDetail.setStatus(3);
                    }
                    apsWorkDetailMapper.updateById(ycWorkDetail);
                }

            }
        }
        WorkDetailTask qg = workDetailTaskMapper.lambdaQuery()
                .eq(WorkDetailTask::getMaterCode, plate)
                .eq(WorkDetailTask::getStatus, 3)
                .eq(WorkDetailTask::getType, 1)
                .in(WorkDetailTask::getPhaseCode, "JG", "HG")
                .one();
        if (ObjectUtils.isEmpty(qg)) {
            return;
        }
        if (org.apache.commons.lang3.StringUtils.equals(qg.getPhaseCode(), WorkshopProp.HG_PHASE_CODE) || org.apache.commons.lang3.StringUtils.equals(qg.getPhaseCode(), WorkshopProp.JG_PHASE_CODE)) {
            for (SinoCamReceiveNestPart nestPart : nestPartList) {
                ApsWorkDetail apsWorkDetail = apsWorkDetailMapper.lambdaQuery()
                        .eq(ApsWorkDetail::getId, nestPart.getNestPlanId())
                        .one();
                if (!ObjectUtils.isEmpty(apsWorkDetail)) {
                    if (apsWorkDetail.getProcessCount() == null) {
                        apsWorkDetail.setProcessCount(new BigDecimal(0));
                    }
                    //大与切割计划，则不进行处理
                    if (apsWorkDetail.getTotalCount().compareTo(apsWorkDetail.getFinishCount()) <= 0) {
                        continue;
                    }
                    apsWorkDetail.setFinishCount(apsWorkDetail.getFinishCount().add(new BigDecimal(nestPart.getQuantity())));
                    apsWorkDetail.setUniqueCode(plate); // 切割报工唯一号塞钢板号
                    apsWorkDetail.setActualStartDateTime(LocalDateTime.now());
                    if (apsWorkDetail.getTotalCount().compareTo(apsWorkDetail.getFinishCount()) <= 0) {
                        apsWorkDetail.setStatus(4);
                        apsWorkDetail.setActualEndDateTime(LocalDateTime.now());
                    } else {
                        apsWorkDetail.setActualStartDateTime(LocalDateTime.now());
                        apsWorkDetail.setStatus(3);
                    }
                    apsWorkDetailMapper.updateById(apsWorkDetail);
                    ApsWorkOrder apsWorkOrder = apsWorkOrderMapper.selectById(apsWorkDetail.getApsWorkOrderId());
                    Order one = orderMapper.lambdaQuery().eq(Order::getId, apsWorkDetail.getOrderId()).one();

                    Part qgPart = partUtilService.createPart(one.getConstructNo(), apsWorkDetail.getMaterNo(), apsWorkDetail.getPhaseSeq(), qg.getPhaseCode(), qg.getPhaseCode(), qg.getPhaseName(), apsWorkOrder.getWorkChain(), qg.getNextGroupCode(), nestPart.getQuantity(), 0);
                    partUtilService.createPartLog(1, qgPart, nestPart.getQuantity(), 0, null, null, null);
                    this.createPartReport(one.getConstructNo(), qg.getGroupCode(), apsWorkDetail, qg.getPhaseCode(), new BigDecimal(nestPart.getQuantity()), reqVo);
                }
            }
        }

        WorkDetailTask fj = workDetailTaskMapper.lambdaQuery()
                .eq(WorkDetailTask::getMaterCode, plate)
                .eq(WorkDetailTask::getStatus, 3)
                .eq(WorkDetailTask::getType, 1)
                .in(WorkDetailTask::getPhaseCode, "FJ")
                .one();
        if (ObjectUtils.isEmpty(fj)) {
            return;
        }
        PartFjTaskCreate(plate);


    }


    public void mesWorkdRecord(String plateCode, String phaseCode, String groupCode, String staffCode, int state) {
        CompletableFuture.runAsync(() -> {
            try {
                DoWorksDto dto = new DoWorksDto();
                dto.setNxphdescr(phaseCode);
                dto.setWorkId(plateCode);
                dto.setWorkPlace(groupCode);
                dto.setStockPlaceName(groupCode);
                dto.setWorkers(staffCode);
                //：start-开工，stop-中止，complete-完工
                if (state == 1) {
                    // 只要开工，直接通知MES
                    dto.setWorkAction("start");
                    log.info(JsonUtils.toJsonString(dto));
                    Result result = apsMesFeign.doWorks(dto);
                    log.info(JsonUtils.toJsonString(result));
                    recordMesPlate(dto.getWorkId(), dto.getStockPlaceName(), dto.getWorkers(), dto.getNxphdescr(), dto.getWorkAction(), result.getCode());
                } else {
                    // 报工去查记录表
                    List<WorkRecordReply> workRecordReplies = workRecordReplyMapper.lambdaQuery()
                            .eq(WorkRecordReply::getPlateCode, dto.getWorkId())
                            .eq(WorkRecordReply::getPhaseCode, dto.getNxphdescr())
                            .eq(WorkRecordReply::getWorkType, 1)
                            .eq(WorkRecordReply::getBackState, 2)
                            .list();
                    if (CollUtil.isNotEmpty(workRecordReplies)) {
                        // 有开工成功的记录，则发送报工
                        dto.setWorkAction("complete");
                        log.info(JsonUtils.toJsonString(dto));
                        Result result = apsMesFeign.doWorks(dto);
                        log.info(JsonUtils.toJsonString(result));
                        recordMesPlate(dto.getWorkId(), dto.getStockPlaceName(), dto.getWorkers(), dto.getNxphdescr(), dto.getWorkAction(), result.getCode());
                    } else {
                        // 没有开工成功记录，先发送开工记录
                        dto.setWorkAction("start");
                        log.info(JsonUtils.toJsonString(dto));
                        Result result = apsMesFeign.doWorks(dto);
                        log.info(JsonUtils.toJsonString(result));
                        recordMesPlate(dto.getWorkId(), dto.getStockPlaceName(), dto.getWorkers(), dto.getNxphdescr(), dto.getWorkAction(), result.getCode());
                        try {
                            // 延时 2 秒后进行发送报工
                            Thread.sleep(2000);
                        } catch (InterruptedException e) {
                            throw new RuntimeException(e);
                        }
                        dto.setWorkAction("complete");
                        result = apsMesFeign.doWorks(dto);
                        log.info(JsonUtils.toJsonString(result));
                        recordMesPlate(dto.getWorkId(), dto.getStockPlaceName(), dto.getWorkers(), dto.getNxphdescr(), dto.getWorkAction(), result.getCode());
                    }
                }

            } finally {

            }
        });

    }

    public void recordMesPlate(String plateCode, String groupCode, String staffCode, String phaseCode, String workAction, Integer success) {
        WorkRecordReply workRecordReply = new WorkRecordReply();
        workRecordReply.setPlateCode(plateCode);
        workRecordReply.setGroupCode(groupCode);
        workRecordReply.setStaffCode(staffCode);
        workRecordReply.setPhaseCode(phaseCode);
        if (org.apache.commons.lang.StringUtils.equals(workAction, "start")) {
            workRecordReply.setWorkType(1);
        } else {
            workRecordReply.setWorkType(2);
        }
        if (success == 0) {
            workRecordReply.setBackState(2);
        } else {
            workRecordReply.setBackState(3);
        }
        workRecordReplyMapper.insert(workRecordReply);
    }

    public void buWorkRecord(List<String> plateList) {
        List<WmsPlatePick> list = wmsPlatePickMapper.lambdaQuery()
//                .gt(WmsPlatePick::getId, 381)
                .in(WmsPlatePick::getMaterialCode, plateList)
                .orderByAsc(WmsPlatePick::getPickListItem)
                .list();
        for (WmsPlatePick wmsPlatePick : list) {
            log.info(JsonUtils.toJsonString(wmsPlatePick));
            List<ApsWorkDetail> list1 = apsWorkDetailMapper.lambdaQuery().eq(ApsWorkDetail::getType, 1).gt(ApsWorkDetail::getStatus, 3).eq(ApsWorkDetail::getMaterNo, wmsPlatePick.getMaterialCode()).gt(ApsWorkDetail::getPhaseSeq, 1).orderByAsc(ApsWorkDetail::getPhaseSeq).list();
            for (ApsWorkDetail apsWorkDetail : list1) {
                try {
                    DoWorksDto dto = new DoWorksDto();
                    //：start-开工，stop-中止，complete-完工
                    dto.setWorkAction("start");
                    dto.setNxphdescr(apsWorkDetail.getPhaseCode());
                    dto.setWorkId(wmsPlatePick.getMaterialCode());
                    dto.setWorkPlace(apsWorkDetail.getGroupCode());
                    dto.setStockPlaceName(apsWorkDetail.getGroupCode());

                    log.info(JsonUtils.toJsonString(dto));
                    Result result = apsMesFeign.doWorks(dto);
                    log.info(JsonUtils.toJsonString(result));
                    try {
                        Thread.sleep(5000);
                    } catch (InterruptedException e) {
                        throw new RuntimeException(e);
                    }
                    dto.setWorkAction("complete");
                    result = apsMesFeign.doWorks(dto);
                    log.info(JsonUtils.toJsonString(result));
                } finally {

                }
            }

        }

    }

    public BasePageResVo<WorkShopFmToComponentListResVo> fmToComponentList(WorkShopFmToComponentListReqVo reqVo) {
        Page<ApsWorkDetail> page = apsWorkDetailMapper.lambdaQuery()
                .eq(ApsWorkDetail::getGroupCode, reqVo.getGroupCode())
                .in(ApsWorkDetail::getStatus, 2, 3)
                .in(ApsWorkDetail::getOrderType, 1, 3, 4)
                .page(reqVo.toPage());
        List<WorkShopFmToComponentListResVo> collect = page.getRecords()
                .stream()
                .map(e -> {
                    WorkShopFmToComponentListResVo r = new WorkShopFmToComponentListResVo();
                    BeanUtils.copyProperties(e, r);
                    return r;
                })
                .collect(Collectors.toList());


        return new BasePageResVo<>(page.getTotal(), collect);
    }

    @Transactional
    public void fmToComponentStart(BaseIdReqVo reqVo) {
        ApsWorkDetail apsWorkDetail = apsWorkDetailMapper.selectById(reqVo.getId());


        ApsWorkDetail awd = new ApsWorkDetail();
        awd.setId(reqVo.getId());
        awd.setModifyDateTime(LocalDateTime.now());
        if (apsWorkDetail.getStatus() <= 1 || apsWorkDetail.getStatus() >= 4) {
            throw SyExceptionUtils.e("该工序已报完!");
        }

        if (apsWorkDetail.getStatus() == 2) {
            awd.setStatus(3);
        }

        awd.setActualStartDateTime(LocalDateTime.now());
        apsWorkDetailMapper.updateById(awd);
    }

    @Transactional
    public void fmToComponentEnd(WorkShopFmToComponentEndReqVo reqVo) {
        ApsWorkDetail apsWorkDetail = apsWorkDetailMapper.selectById(reqVo.getId());
        if (apsWorkDetail.getFinishCount().add(new BigDecimal(reqVo.getTotalCount())).compareTo(apsWorkDetail.getTotalCount()) > 0) {
            throw SyExceptionUtils.e("数量溢出");
        }

        Order o = orderMapper.selectById(apsWorkDetail.getOrderId());

        apsWorkDetail.setFinishCount(apsWorkDetail.getFinishCount().add(new BigDecimal(reqVo.getTotalCount())));
        apsWorkDetail.setActualEndDateTime(LocalDateTime.now());
        if (apsWorkDetail.getFinishCount().compareTo(apsWorkDetail.getTotalCount()) == 0) {
            apsWorkDetail.setStatus(4);
        }
        apsWorkDetailMapper.updateById(apsWorkDetail);

        // 补一个赋码的task
        WorkDetailTask task = new WorkDetailTask();
        MkBeanUtils.copyPropertiesIgnore(apsWorkDetail, task);
        task.setMaterCode(apsWorkDetail.getMaterNo());
        task.setMaterName(apsWorkDetail.getMaterName());
        task.setApsWorkDetailId(apsWorkDetail.getId());
        task.setTotalCount(reqVo.getTotalCount());
        task.setFinishCount(reqVo.getTotalCount());
        task.setFailCount(0);
        task.setType(2);
        task.setPlanStartDateTime(apsWorkDetail.getPlanStartDateTime());
        task.setPlanEndDateTime(apsWorkDetail.getPlanEndDateTime());
        task.setGroupCode(apsWorkDetail.getGroupCode());
        task.setPlmid(apsWorkDetail.getPlmId());
        task.setPhaseCode(apsWorkDetail.getPhaseCode());
        task.setPhaseName(apsWorkDetail.getPhaseName());
        task.setStatus(3);
        workDetailTaskMapper.insert(task);

        // 增一下喷涂的task
        QueryWrapper<ApsWorkDetail> query = Wrappers.query();
        query.gt("phase_seq", apsWorkDetail.getPhaseSeq());
        query.eq("aps_work_order_id", apsWorkDetail.getApsWorkOrderId());
        Integer minPhaseSeq = apsWorkDetailMapper.minPhaseSeq(query);

        // 如果没有下一道工序，则回退
        if (minPhaseSeq == null) {
            // 有一块没写，本组是否完成
            return;
        }

        List<ApsWorkDetail> list = apsWorkDetailMapper.lambdaQuery()
                .eq(ApsWorkDetail::getApsWorkOrderId, apsWorkDetail.getApsWorkOrderId())
                .in(ApsWorkDetail::getStatus, 2, 3)
                .isNull(ApsWorkDetail::getUniqueCode)
                .eq(ApsWorkDetail::getPhaseSeq, minPhaseSeq)
                .list();

        int allTotal = reqVo.getTotalCount();
        for (ApsWorkDetail nextDetail : list) {

            int total = 0; // 此次扣减数

            int wdTotal = nextDetail.getTotalCount().subtract(nextDetail.getFinishCount()).intValue();
            if (wdTotal >= allTotal) {
                total = allTotal;
                allTotal = 0;
            } else {
                total = wdTotal;
                allTotal = allTotal - wdTotal;
            }

            nextDetail.setUniqueCode(mkPartUtils.getUniqueCode(o.getConstructNo(), nextDetail.getPlmId(), nextDetail.getMaterName()));
            apsWorkDetailMapper.updateById(nextDetail);

            WorkDetailTask nextTask = new WorkDetailTask();
            MkBeanUtils.copyPropertiesIgnore(nextDetail, nextTask);
            nextTask.setApsWorkDetailId(nextDetail.getId());
            nextTask.setTotalCount(total);
            nextTask.setFinishCount(0);
            nextTask.setFailCount(0);
            nextTask.setType(2);
            nextTask.setPlmid(apsWorkDetail.getPlmId());
            workDetailTaskMapper.insert(nextTask);
            if (allTotal == 0) {
                break;
            }
        }


    }


    public void addPart(String plmid, String phaseCode, int count, String constructNo) {
        Part part = null;
        plmid = plmid.trim();
        //  分拣特殊处理
        if (org.apache.commons.lang3.StringUtils.equalsIgnoreCase(phaseCode, "FJ")) {
            List<SinoCamReceiveNestPart> nestPartList = sinoCamReceiveNestPartMapper.lambdaQuery()
                    .eq(SinoCamReceiveNestPart::getPartId, plmid)
                    .list();
            List<SinoCamReceiveNestPart> collect = nestPartList.stream().filter(e -> e.getQuantity() - e.getSortingCount() == count).collect(Collectors.toList());
            if (!CollectionUtils.isEmpty(collect)) {
                SinoCamReceiveNestPart nestPart = collect.get(0);
                ApsWorkDetail workQgDetail = apsWorkDetailMapper.selectById(Integer.parseInt(nestPart.getNestPlanId()));
                ApsWorkDetail apsWorkDetail = apsWorkDetailMapper.lambdaQuery()
                        .eq(ApsWorkDetail::getMaterNo, nestPart.getPartId())
                        .eq(ApsWorkDetail::getApsWorkOrderId, workQgDetail.getApsWorkOrderId())
                        .eq(ApsWorkDetail::getPhaseCode, WorkshopProp.FJ_PHASE_CODE).one();
                if (apsWorkDetail.getFinishCount().compareTo(apsWorkDetail.getTotalCount())>=0) {
                    apsWorkDetail.setFinishCount(apsWorkDetail.getTotalCount().subtract(new BigDecimal(count)));
                }
                apsWorkDetail.setStatus(3);
                apsWorkDetailMapper.updateById(apsWorkDetail);
                LambdaQueryWrapper<Part> partwar = new LambdaQueryWrapper();
                partwar.eq(Part::getPlmId, plmid);
                partwar.eq(Part::getPhaseCode, phaseCode);
                if (StringUtils.hasText(constructNo)) {
                    partwar.eq(Part::getConstructNo, constructNo);
                }
                boolean flage=true;
                List<Part> list = partMapper.selectList(partwar);
                if (CollectionUtils.isEmpty(list) && StringUtils.hasText(constructNo)) {
                    flage=false;
                    list = partMapper.lambdaQuery().eq(Part::getPlmId, plmid).eq(Part::getPhaseCode, phaseCode).list();
                }
                if (!CollectionUtils.isEmpty(list)) {
                    if(flage){
                        part = list.get(0);
                        part.setPartCount(part.getPartCount() + count);
                        partMapper.updateById(part);
                    }else{
                        Part  partn=new Part();
                        BeanUtils.copyProperties( list.get(0),partn);
                        partn.setId(null);
                        partn.setConstructNo(constructNo);
                        partn.setPartCount( count);
                        partMapper.insert(partn);
                    }

                } else {
                    list = partMapper.lambdaQuery().eq(Part::getPlmId, plmid).list();
                    if (!CollectionUtils.isEmpty(list)) {
                        part = list.get(0);
                        part.setId(null);
                        part.setPartCount(count);
                        part.setConstructNo(constructNo);
                        part.setPhaseCode(phaseCode);
                        String[] chains = part.getWorkChain().split("-");
                        int index = 0;
                        for (int i = 0; i < chains.length; i++) {
                            if (org.apache.commons.lang.StringUtils.equalsIgnoreCase(chains[i], phaseCode)) {
                                index = i;
                                break;
                            }
                        }
                        part.setPrePhaseCode(chains[index - 1]);
                        partMapper.insert(part);
                    }

                }
            }


            return;
        }

        if (org.apache.commons.lang3.StringUtils.equalsIgnoreCase(phaseCode, "KJ")) {
            LambdaQueryWrapper<Part> partwar = new LambdaQueryWrapper();
            partwar.eq(Part::getPlmId, plmid);
            partwar.eq(Part::getPhaseCode, phaseCode);
            if (StringUtils.hasText(constructNo)) {
                partwar.eq(Part::getConstructNo, constructNo);
            }
            boolean flage=true;
            List<Part> list = partMapper.selectList(partwar);
            if (CollectionUtils.isEmpty(list) && StringUtils.hasText(constructNo)) {
                flage=false;
                list = partMapper.lambdaQuery().eq(Part::getPlmId, plmid).eq(Part::getPhaseCode, phaseCode).list();
            }
            if (!CollectionUtils.isEmpty(list)) {
                if(flage){
                    part = list.get(0);
                    part.setPartCount(part.getPartCount() + count);
                    partMapper.updateById(part);
                }else{
                    Part  partn=new Part();
                    BeanUtils.copyProperties( list.get(0),partn);
                    partn.setId(null);
                    partn.setConstructNo(constructNo);
                    partn.setPartCount( count);
                    partMapper.insert(partn);
                }

            } else {
                list = partMapper.lambdaQuery().eq(Part::getPlmId, plmid).list();
                if (!CollectionUtils.isEmpty(list)) {
                    part = list.get(0);
                    part.setId(null);
                    part.setPartCount(count);
                    part.setPhaseCode(phaseCode);
                    part.setConstructNo(constructNo);
                    String[] chains = part.getWorkChain().split("-");
                    int index = 0;
                    for (int i = 0; i < chains.length; i++) {
                        if (org.apache.commons.lang.StringUtils.equalsIgnoreCase(chains[i], phaseCode)) {
                            index = i;
                            break;
                        }
                    }
                    if (index == 0) {
                        part.setPrePhaseCode(chains[chains.length - 1]);
                    } else {
                        part.setPrePhaseCode(chains[index - 1]);
                    }
                    partMapper.insert(part);
                }else{
                    Part  partn=new Part();
                    partn.setConstructNo(constructNo);
                    partn.setPartCount( count);
                    partn.setPlmId(plmid);
                    partn.setPhaseCode(WorkshopProp.KJ_PHASE_CODE);
                    partn.setFailCount(0);
                    partn.setPartType(2);
                    partn.setWorkChain(WorkshopProp.KJ_PHASE_CODE);
                    partMapper.insert(partn);
                }

            }
            return;
        }
        // 维护在制品
        LambdaQueryWrapper<Part> partwar = new LambdaQueryWrapper<>();
        partwar.eq(Part::getPlmId, plmid);
        partwar.eq(Part::getPhaseCode, phaseCode);
        if (StringUtils.hasText(constructNo)) {
            partwar.eq(Part::getConstructNo, constructNo);
        }
        List<Part> list = partMapper.selectList(partwar);
        boolean flage=true;
        if (CollectionUtils.isEmpty(list) && StringUtils.hasText(constructNo)) {
            flage=false;
            list = partMapper.lambdaQuery().eq(Part::getPlmId, plmid).eq(Part::getPhaseCode, phaseCode).list();
        }
        if (!CollectionUtils.isEmpty(list)) {
            if(flage){
                part = list.get(0);
                part.setPartCount(part.getPartCount() + count);
                partMapper.updateById(part);
            }else{
                Part  partn=new Part();
                BeanUtils.copyProperties( list.get(0),partn);
                partn.setId(null);
                partn.setConstructNo(constructNo);
                partn.setPartCount( count);
                partMapper.insert(partn);
            }



        } else {
            list = partMapper.lambdaQuery().eq(Part::getPlmId, plmid).list();
            if (!CollectionUtils.isEmpty(list)) {
                part = list.get(0);
                part.setId(null);
                part.setPartCount(count);
                part.setConstructNo(constructNo);
                part.setPhaseCode(phaseCode);
                String[] chains = part.getWorkChain().split("-");
                int index = 0;
                for (int i = 0; i < chains.length; i++) {
                    if (org.apache.commons.lang.StringUtils.equalsIgnoreCase(chains[i], phaseCode)) {
                        index = i;
                        break;
                    }
                }
                part.setPrePhaseCode(chains[index - 1]);
                partMapper.insert(part);
            } else {
                List<WorkDetailTask> taskList = workDetailTaskMapper.lambdaQuery()
                        .eq(WorkDetailTask::getMaterCode, plmid)
                        .lt(WorkDetailTask::getStatus, 3)
                        .eq(WorkDetailTask::getPhaseCode, phaseCode)
                        .list();
                if (!CollectionUtils.isEmpty(taskList)) {
                    list = partMapper.lambdaQuery().eq(Part::getPartType, 2).ne(Part::getPhaseCode, WorkshopProp.KJ_PHASE_CODE).last("limit 1").list();
                    part = list.get(0);
                    part.setId(null);
                    part.setPartCount(count);
                    part.setConstructNo(constructNo);
                    part.setPhaseCode(phaseCode);
                    part.setPlmId(plmid);
                    partMapper.insert(part);
                }

            }

        }
        if (part != null) {
            int addCount = count;//  缺几个任务
            List<WorkDetailTask> taskList = workDetailTaskMapper.lambdaQuery()
                    .eq(WorkDetailTask::getMaterCode, plmid)
                    .lt(WorkDetailTask::getStatus, 3)
                    .eq(WorkDetailTask::getPhaseCode, phaseCode)
                    .list();
            for (WorkDetailTask task : taskList) {
                addCount = addCount - task.getTotalCount() + task.getFinishCount();
            }

            if (addCount < 1) {
                return;
            }
            List<ApsWorkDetail> nextList = apsWorkDetailMapper.lambdaQuery()
                    .eq(ApsWorkDetail::getMaterNo, plmid)
                    .in(ApsWorkDetail::getStatus, 2, 3)
                    .eq(ApsWorkDetail::getPhaseCode, phaseCode)
                    .orderByAsc(ApsWorkDetail::getId)
                    .list();

            for (ApsWorkDetail apsWorkDetail : nextList) {
                int partCount = apsWorkDetail.getTotalCount().intValue() - apsWorkDetail.getFinishCount().intValue();
                if (partCount >= addCount) {
                    // 根据计划创建任务
                    partUtilService.makeWorkDetailTask(apsWorkDetail, new BigDecimal(addCount), null, part.getPrePhaseCode());
                    addCount = 0;
                    break;
                } else {
                    addCount = addCount - partCount;
                    partUtilService.makeWorkDetailTask(apsWorkDetail, new BigDecimal(partCount), null, part.getPrePhaseCode());
                }


            }
            //  计划不够的话
            if (addCount > 0) {
                List<WorkDetailTask> taskfinshList = workDetailTaskMapper.lambdaQuery()
                        .eq(WorkDetailTask::getMaterCode, plmid)
                        .eq(WorkDetailTask::getStatus, 3)
                        .eq(WorkDetailTask::getPhaseCode, phaseCode)
                        .list();
                if (!CollectionUtils.isEmpty(taskfinshList)) {
                    WorkDetailTask t = taskfinshList.get(0);
                    t.setTotalCount(t.getTotalCount() + addCount);
                    t.setStatus(2);
                    workDetailTaskMapper.updateById(t);

                }
            }


        }


    }

    @Transactional
    public void assemblePdaEnd(WorkshopAssembleEndReqVo reqVo) {
        if (reqVo.getStationCode().trim().contains("DLPX") || reqVo.getStationCode().trim().contains("DZPX")
                || reqVo.getStationCode().trim().contains("YLPX")) {
            ApsWorkDetail apsWorkDetail = apsWorkDetailMapper.lambdaQuery()
                    .eq(ApsWorkDetail::getApsWorkOrderId, reqVo.getId())
                    .eq(ApsWorkDetail::getStatus, 3)// 待开工 如果2,3的话会总是更新第一条数据
                    .last("limit 1")
                    .one();
            if (StringUtils.hasText(apsWorkDetail.getMaterName()) && apsWorkDetail.getMaterName().contains("顶板")) {
                //顶板可以进行批量报工
                List<ApsWorkDetail> list = apsWorkDetailMapper.lambdaQuery()
                        .eq(ApsWorkDetail::getApsWorkOrderId, reqVo.getId())
                        .eq(ApsWorkDetail::getStatus, 3)// 待开工 如果2,3的话会总是更新第一条数据
                        .last("limit " + reqVo.getQuantity())
                        .list();
                for (ApsWorkDetail detail : list) {
                    reqVo.setId(detail.getId());
                    reqVo.setQuantity(1);
                    assemblePdEnd(reqVo);
                }
            } else {
                reqVo.setId(apsWorkDetail.getId());
                assemblePdEnd(reqVo);
            }

        } else {
            //拼点 报工
            assemblePdEnd(reqVo);

        }

    }

    public List<CheckdPartVo> checkdPart(String plmid) {
        return workshopMapper.checkdPart(plmid);
    }

    public void partBatchStart(EmbeddedStartModel reqVo) {

        QueryWrapper<WorkDetailTask> objectQueryWrapper = new QueryWrapper<>();
        objectQueryWrapper.eq("tm.plmid", reqVo.getAssemblyNumber());
        objectQueryWrapper.eq("tm.group_code", reqVo.getWorkPlaceName());
        if (StringUtils.hasText(reqVo.getConstructNo())) {
            objectQueryWrapper.eq("tr.construct_no", reqVo.getConstructNo());
        }
        objectQueryWrapper.eq("tm.status", 1);
        objectQueryWrapper.eq("tm.deleted", 0);
        List<WorkDetailTask> taskList = workDetailTaskMapper.getTasklist(objectQueryWrapper);
        if (taskList.isEmpty()) {
            throw SyExceptionUtils.e("{}没有找到开工中的任务", reqVo.getAssemblyNumber());
        }
        for (WorkDetailTask task : taskList) {
            WorkshopPartStartWorkReqVo start=new WorkshopPartStartWorkReqVo();
            start.setId(task.getId());
            start.setPlmid(task.getPlmid());
            start.setPhaseCode(task.getPhaseCode());
            start.setStationCode(reqVo.getWorkPlaceName().trim());
            start.setStaffCode(reqVo.getWorker());
            partStartWorkNew(start);
        }
    }

    public Order getOrder(String constructionNo, String plmid) {
        return orderMapper.lambdaQuery()
                .eq(Order::getConstructNo, constructionNo)
                .eq(Order::getPlmId, plmid)
                .last("limit 1")
                .one();
    }


}